Exemplo n.º 1
0
def createCTL(type="square", child=False, *args):
    """Create a control for each selected object.

    The newly create control can be parent or child of the object.

    Args:
        type (str): The shape of the control.
        child (bool): if True, the control will be created as a
            child of the object.

    """
    iconList = []
    if child:
        if len(pm.selected()) > 0:
            for x in pm.selected():
                oChilds = [item for item
                           in x.listRelatives(ad=True, type="transform")
                           if item.longName().split("|")[-2] == x.name()]

                o_icon = icon.create(
                    None, x.name() + "_ctl", None, [1, 0, 0], type)
                iconList.append(o_icon)
                o_icon.setTransformation(x.getMatrix(worldSpace=True))
                pm.parent(o_icon, x)
                for child in oChilds:

                    pm.parent(child, o_icon)
        else:

            o_icon = icon.create(
                None, type + "_ctl", datatypes.Matrix(), [1, 0, 0], type)
            iconList.append(o_icon)
    else:
        if len(pm.selected()) > 0:
            for x in pm.selected():
                oParent = x.getParent()
                o_icon = icon.create(oParent,
                                     x.name() + "_ctl",
                                     x.getMatrix(),
                                     [1, 0, 0],
                                     type)
                iconList.append(o_icon)
                o_icon.setTransformation(x.getMatrix())
                pm.parent(x, o_icon)
        else:

            o_icon = icon.create(
                None, type + "_ctl", datatypes.Matrix(), [1, 0, 0], type)
            iconList.append(o_icon)

    try:
        defSet = pm.PyNode("rig_controllers_grp")
        for ico in iconList:
            pm.sets(defSet, add=ico)
    except TypeError:
        print "not rig_controllers_grp found"
        pass
Exemplo n.º 2
0
def createJntTweak(mesh, parentJnt, ctlParent):
    """Create a joint tweak

    Args:
        mesh (mesh): The object to deform with the tweak
        parentJnt (dagNode): The parent for the new joint
        ctlParent (dagNode): The parent for the control.
    """
    if not isinstance(mesh, list):
        mesh = [mesh]

    name = "_".join(parentJnt.name().split("_")[:3])

    # create joints
    jointBase = primitive.addJoint(parentJnt, name + "_tweak_jnt_lvl",
                                   parentJnt.getMatrix(worldSpace=True))
    resetJntLocalSRT(jointBase)
    joint = primitive.addJoint(jointBase, name + "_tweak_jnt",
                               parentJnt.getMatrix(worldSpace=True))
    resetJntLocalSRT(joint)

    # hidding joint base by changing the draw mode
    # pm.setAttr(jointBase+".drawStyle", 2)

    try:
        defSet = pm.PyNode("rig_deformers_grp")
    except TypeError:
        pm.sets(n="rig_deformers_grp")
        defSet = pm.PyNode("rig_deformers_grp")
    pm.sets(defSet, add=joint)

    controlType = "circle"
    iconBase = icon.create(ctlParent,
                           name + "_base_tweak_ctl",
                           ctlParent.getMatrix(worldSpace=True),
                           13,
                           controlType,
                           w=.8,
                           ro=datatypes.Vector(0, 0, 1.5708))
    o_icon = icon.create(iconBase,
                         name + "_tweak_ctl",
                         ctlParent.getMatrix(worldSpace=True),
                         17,
                         controlType,
                         w=.5,
                         ro=datatypes.Vector(0, 0, 1.5708))

    for t in [".translate", ".scale", ".rotate"]:
        pm.connectAttr(iconBase + t, jointBase + t)
        pm.connectAttr(o_icon + t, joint + t)

    # magic of doritos connection
    for m in mesh:
        doritosMagic(m, joint, jointBase)
Exemplo n.º 3
0
    def addCtl(self, parent, name, m, color, icon, **kwargs):
        """
        Create the control and apply the shape, if this is alrealdy stored
        in the guide controllers grp.

        Args:
            parent (dagNode): The control parent
            name (str): The control name.
            m (matrix): The transfromation matrix for the control.
            color (int or list of float): The color for the control in idex or RGB.
            icon (str): The controls default shape.
            kwargs (variant): Other arguments for the icon type variations.

        Returns:
            dagNode: The Control.

        """
        if name in self.guide.controllers.keys():
            ctl_ref = self.guide.controllers[name]
            ctl = pri.addTransform(parent, name, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
        else:
            ctl = ico.create(parent, name, m, color, icon, **kwargs)

        self.addToGroup(ctl, "controllers")

        return ctl
Exemplo n.º 4
0
    def addCtl(self, parent, name, m, color, icon, **kwargs):

        if name in self.guide.controlers.keys():
            ctl_ref = self.guide.controlers[name]
            ctl = pri.addTransform(parent, name, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
        else:
            ctl = ico.create(parent, name, m, color, icon, **kwargs)
            
        self.addToGroup(ctl, "controlers")
        
        return ctl
Exemplo n.º 5
0
    def addCtl(self, parent, name, m, color, icon, **kwargs):

        if name in self.guide.controlers.keys():
            ctl_ref = self.guide.controlers[name]
            ctl = pri.addTransform(parent, name, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
        else:
            ctl = ico.create(parent, name, m, color, icon, **kwargs)

        self.addToGroup(ctl, "controlers")

        return ctl
Exemplo n.º 6
0
    def addCtl(self, parent, name, m, color, iconShape, **kwargs):
        """Create the control and apply the shape, if this is alrealdy stored
        in the guide controllers grp.

        Args:
            parent (dagNode): The control parent
            name (str): The control name.
            m (matrix): The transfromation matrix for the control.
            color (int or list of float): The color for the control in index
                or RGB.
            iconShape (str): The controls default shape.
            kwargs (variant): Other arguments for the iconShape type variations

        Returns:
            dagNode: The Control.

        """
        if "degree" not in kwargs.keys():
            kwargs["degree"] = 1

        bufferName = name + "_controlBuffer"
        if bufferName in self.guide.controllers.keys():
            ctl_ref = self.guide.controllers[bufferName]
            ctl = primitive.addTransform(parent, name, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
                pm.rename(shape, name + "Shape")
        else:
            ctl = icon.create(parent, name, m, color, iconShape, **kwargs)

        self.addToGroup(ctl, "controllers")

        # Set the control shapes isHistoricallyInteresting
        for oShape in ctl.getShapes():
            oShape.isHistoricallyInteresting.set(False)

        # set controller tag
        if versions.current() >= 201650:
            pm.controller(ctl)
            self.add_controller_tag(ctl, None)

        return ctl
Exemplo n.º 7
0
    def addCtl(self, parent, name, m, color, icon, **kwargs):
        """
        Create the control and apply the shape, if this is alrealdy stored
        in the guide controllers grp.

        Args:
            parent (dagNode): The control parent
            name (str): The control name.
            m (matrix): The transfromation matrix for the control.
            color (int or list of float): The color for the control in idex or RGB.
            icon (str): The controls default shape.
            kwargs (variant): Other arguments for the icon type variations.

        Returns:
            dagNode: The Control.

        """
        fullName = self.getName(name)
        if fullName in self.rig.guide.controllers.keys():
            ctl_ref = self.rig.guide.controllers[fullName]
            ctl = pri.addTransform(parent, fullName, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
            ico.setcolor(ctl, color)
        else:
            ctl = ico.create(parent, fullName, m, color, icon, **kwargs)

        # create the attributes to handlde mirror and symetrical pose
        att.addAttribute(ctl, "invTx", "bool", 0,  keyable=False, niceName="Invert Mirror TX")
        att.addAttribute(ctl, "invTy", "bool", 0,  keyable=False, niceName="Invert Mirror TY")
        att.addAttribute(ctl, "invTz", "bool", 0,  keyable=False, niceName="Invert Mirror TZ")
        att.addAttribute(ctl, "invRx", "bool", 0,  keyable=False, niceName="Invert Mirror RX")
        att.addAttribute(ctl, "invRy", "bool", 0,  keyable=False, niceName="Invert Mirror RY")
        att.addAttribute(ctl, "invRz", "bool", 0,  keyable=False, niceName="Invert Mirror RZ")
        att.addAttribute(ctl, "invSx", "bool", 0,  keyable=False, niceName="Invert Mirror SX")
        att.addAttribute(ctl, "invSy", "bool", 0,  keyable=False, niceName="Invert Mirror SY")
        att.addAttribute(ctl, "invSz", "bool", 0,  keyable=False, niceName="Invert Mirror SZ")

        self.addToGroup(ctl, "controllers")

        return ctl
Exemplo n.º 8
0
def createRivetTweak(mesh,
                     edgePair,
                     name,
                     parent=None,
                     ctlParent=None,
                     color=[0, 0, 0],
                     size=.04,
                     defSet=None):
    """Create a tweak joint attached to the mesh using a rivet

    Args:
        mesh (mesh): The object to add the tweak
        edgePair (pari list): The edge pairt to create the rivet
        name (str): The name for the tweak
        parent (None or dagNode, optional): The parent for the tweak
        ctlParent (None or dagNode, optional): The parent for the tweak control
        color (list, optional): The color for the control
    """
    blendShape = blendShapes.getBlendShape(mesh)

    inputMesh = blendShape.listConnections(sh=True, t="shape", d=False)[0]

    oRivet = rivet.rivet()
    base = oRivet.create(inputMesh, edgePair[0], edgePair[1], parent)
    # get side
    if base.getTranslation(space='world')[0] < -0.01:
        side = "R"
    elif base.getTranslation(space='world')[0] > 0.01:
        side = "L"
    else:
        side = "C"

    nameSide = name + "_tweak_" + side
    pm.rename(base, nameSide)

    # Joints NPO
    npo = pm.PyNode(
        pm.createNode("transform", n=nameSide + "_npo", p=ctlParent, ss=True))
    pm.pointConstraint(base, npo)

    # set proper orientation
    pos = base.getTranslation(space="world")
    temp = pm.spaceLocator()
    pm.parent(temp, base)
    temp.attr("ty").set(0)
    temp.attr("tz").set(0)
    temp.attr("tx").set(1)
    lookat = temp.getTranslation(space="world")

    up = datatypes.Vector(0, 1, 0)

    t = transform.getTransformLookingAt(pos,
                                        lookat,
                                        up,
                                        axis="xy",
                                        negate=False)
    npo.setMatrix(t, worldSpace=True)
    pm.delete(temp)

    # create joints
    jointBase = primitive.addJoint(npo, nameSide + "_jnt_lvl")
    joint = primitive.addJoint(jointBase, nameSide + "_jnt")

    # hidding joint base by changing the draw mode
    pm.setAttr(jointBase + ".drawStyle", 2)
    if not defSet:
        try:
            defSet = pm.PyNode("rig_deformers_grp")
        except TypeError:
            pm.sets(n="rig_deformers_grp")
            defSet = pm.PyNode("rig_deformers_grp")
    pm.sets(defSet, add=joint)

    controlType = "sphere"
    o_icon = icon.create(jointBase,
                         nameSide + "_ctl",
                         datatypes.Matrix(),
                         color,
                         controlType,
                         w=size)
    for t in [".translate", ".scale", ".rotate"]:
        pm.connectAttr(o_icon + t, joint + t)

    # create the attributes to handlde mirror and symetrical pose
    attribute.addAttribute(o_icon,
                           "invTx",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror TX")
    attribute.addAttribute(o_icon,
                           "invTy",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror TY")
    attribute.addAttribute(o_icon,
                           "invTz",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror TZ")
    attribute.addAttribute(o_icon,
                           "invRx",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror RX")
    attribute.addAttribute(o_icon,
                           "invRy",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror RY")
    attribute.addAttribute(o_icon,
                           "invRz",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror RZ")
    attribute.addAttribute(o_icon,
                           "invSx",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror SX")
    attribute.addAttribute(o_icon,
                           "invSy",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror SY")
    attribute.addAttribute(o_icon,
                           "invSz",
                           "bool",
                           0,
                           keyable=False,
                           niceName="Invert Mirror SZ")

    # magic of doritos connection
    doritosMagic(mesh, joint, jointBase)

    # reset axis and inver behaviour
    for axis in "XYZ":
        pm.setAttr(jointBase + ".jointOrient" + axis, 0)
        pm.setAttr(npo + ".translate" + axis, 0)
        pm.setAttr(jointBase + ".translate" + axis, 0)

    p = o_icon.getParent().getParent()
    pp = p.getParent()
    pm.parent(p, w=True)
    for axis in "xyz":
        p.attr("r" + axis).set(0)
    if side == "R":
        p.attr("ry").set(180)
        p.attr("sz").set(-1)
    pm.parent(p, pp)

    return o_icon
Exemplo n.º 9
0
def simpleRig(rigName="rig", wCntCtl=False, *args):
    """Create a simple 1Click rig.

    Args:
        rigName (str, optional): Name of the rig.
        wCntCtl (bool, optional): Place the Golbal control in the wolrd
            center or use the general BBox of the selection.
        *args: Description

    Returns:
        dagNode: Rig top node
    """
    meshList = []
    ctlList = []
    lvlList = []
    absBB = []
    absRadio = 0.5

    listSelection = [oSel for oSel in pm.selected()]

    # Create base structure
    rig = pm.createNode('transform', n=rigName)
    geo = pm.createNode('transform', n="geo", p=rig)
    geo.attr("overrideEnabled").set(1)
    geo.attr("overrideDisplayType").set(2)

    attribute.addAttribute(rig, "is_rig", "bool", True)
    attribute.addAttribute(rig, "rig_name", "string", "rig")
    attribute.addAttribute(rig, "user", "string", getpass.getuser())
    attribute.addAttribute(rig, "date", "string", str(datetime.datetime.now()))

    attribute.addAttribute(rig, "maya_version", "string",
                           str(pm.mel.eval("getApplicationVersionAsFloat")))

    attribute.addAttribute(rig, "gear_version", "string", mgear.getVersion())
    attribute.addAttribute(rig, "ctl_vis", "bool", True)
    attribute.addAttribute(rig, "jnt_vis", "bool", False)

    attribute.addAttribute(rig, "quickselA", "string", "")
    attribute.addAttribute(rig, "quickselB", "string", "")
    attribute.addAttribute(rig, "quickselC", "string", "")
    attribute.addAttribute(rig, "quickselD", "string", "")
    attribute.addAttribute(rig, "quickselE", "string", "")
    attribute.addAttribute(rig, "quickselF", "string", "")

    rig.addAttr("rigGroups", at='message', m=1)
    rig.addAttr("rigPoses", at='message', m=1)

    for oSel in listSelection:

        bbCenter, bbRadio, bb = bBoxData(oSel)
        lvl = pm.createNode('transform', n=oSel.name().split("_")[0] + "_npo")
        lvlList.append(lvl)
        t = transform.getTransformFromPos(bbCenter)
        lvl.setTransformation(t)

        ctl = ico.create(lvl,
                         oSel.name().split("_")[0] + "_ctl",
                         t,
                         14,
                         icon="circle",
                         w=bbRadio * 2)

        cnsPart(ctl, oSel)

        ctlList.append(ctl)
        for oShape in oSel.listRelatives(ad=True, s=True, type='mesh'):
            pm.connectAttr(ctl + ".visibility", oShape + ".visibility", f=True)
            meshList.append(oShape)

        # Reparenting
        pm.parent(oSel, geo)

        # calculate the global control BB
        if not wCntCtl:
            if not absBB:
                absBB = bb
            else:
                absBB = [
                    [min(bb[0][0], absBB[0][0]),
                     max(bb[0][1], absBB[0][1])],
                    [min(bb[1][0], absBB[1][0]),
                     max(bb[1][1], absBB[1][1])],
                    [min(bb[2][0], absBB[2][0]),
                     max(bb[2][1], absBB[2][1])]
                ]

        userPivots = dag.findChildrenPartial(oSel, PIVOT_EXTENSION)
        # Loop selection
        uPivotCtl = []
        if userPivots:
            for uPivot in userPivots:
                try:
                    pstr = uPivot.name().split('_')[0] + "_" + PGROUP_EXTENSION
                    pgrp = pm.PyNode(pstr)
                except TypeError:
                    pm.displayError("The selected pivot dont have the group"
                                    " contrapart. Review your rig structure")
                    return False
                objList = pgrp.listRelatives(ad=True)
                if objList:
                    bbCenter, bbRadio, bb = bBoxData(objList)
                    t = uPivot.getMatrix(worldSpace=True)
                    lvlParent = pm.listRelatives(
                        uPivot, p=True)[0].name().split("_")[0] + "_ctl"

                    lvl = pm.createNode('transform',
                                        n=uPivot.split("_")[0] + "_npo")
                    lvl.setTransformation(t)
                    icon = iconList[uPivot.attr("ctlIcon").get()]
                    ctlKeyable = []
                    if uPivot.attr("animTranslation").get():
                        ctlKeyable = ctlKeyable + ["tx", "ty", "tz"]
                    if uPivot.attr("animRotation").get():
                        ctlKeyable = ctlKeyable + ["ro", "rx", "ry", "rz"]
                    if uPivot.attr("animScale").get():
                        ctlKeyable = ctlKeyable + ["sx", "sy", "sz"]

                    ctl = ico.create(lvl,
                                     uPivot.split("_")[0] + "_ctl",
                                     t,
                                     15,
                                     icon=icon,
                                     w=bbRadio * 2,
                                     h=bbRadio * 2,
                                     d=bbRadio * 2)

                    attribute.setKeyableAttributes(ctl, ctlKeyable)
                    pm.parent(lvl, lvlParent)
                    attribute.setKeyableAttributes(lvl, [])
                    uPivotCtl.append(ctl)
                    # Constraint
                    cnsPart(ctl, pgrp)

                    for oShape in uPivot.listRelatives(ad=True,
                                                       s=True,
                                                       type='mesh'):
                        pm.connectAttr(ctl + ".visibility",
                                       oShape + ".visibility",
                                       f=True)
                        meshList.append(oShape)

                    # hidde user pivot
                    uPivot.attr("visibility").set(False)

    # setting the global control
    if wCntCtl:
        absCenter = [0, 0, 0]
    else:
        absCenter = [(axis[0] + axis[1]) / 2 for axis in absBB]
        # set the cencter in the floor
        absCenter[1] = absBB[1][0]

        absRadio = max([absBB[0][1] - absBB[0][0], absBB[2][1] - absBB[2][0]
                        ]) / 1.7

    t = transform.getTransformFromPos(absCenter)
    lvl = pm.createNode('transform', n="global_npo")
    lvl.setTransformation(t)
    pm.parent(lvl, rig)

    ctlGlobal = ico.create(lvl,
                           "global_ctl",
                           t,
                           17,
                           icon="square",
                           w=absRadio * 2,
                           d=absRadio * 2)

    pm.parent(lvlList, ctlGlobal)
    ctlList.append(ctlGlobal)
    attribute.setKeyableAttributes(lvl, [])
    for lvl in lvlList:
        attribute.setKeyableAttributes(lvl, [])

    # Create sets
    meshSet = pm.sets(meshList, n="CACHE_grp")
    ctlSet = pm.sets([ctlList, uPivotCtl], n="rig_controllers_grp")
    deformersSet = pm.sets(meshList, n="rig_deformers_grp")
    compGroup = pm.sets(meshList, n="rig_componentsRoots_grp")

    rigSets = pm.sets([meshSet, ctlSet, deformersSet, compGroup],
                      n="rig_Sets_grp")

    pm.connectAttr(rigSets.attr("message"), "rig.rigGroups[0]")
    pm.connectAttr(meshSet.attr("message"), "rig.rigGroups[1]")
    pm.connectAttr(ctlSet.attr("message"), "rig.rigGroups[2]")
    pm.connectAttr(deformersSet.attr("message"), "rig.rigGroups[3]")
    pm.connectAttr(compGroup.attr("message"), "rig.rigGroups[4]")

    if oSel.hasAttr("animSets") and oSel.attr("animSets").get():
        # create anim Sets
        pm.sets(n="animNodes", em=True)
        animNodes_set = pm.PyNode("animNodes")

        pm.sets(n="animSets", em=True)
        animSets_set = pm.PyNode("animSets")

        # adding set
        pm.sets(animSets_set, add=animNodes_set)
        pm.sets(animNodes_set, add=ctlSet.members())

        pm.connectAttr(animSets_set.attr("message"), "rig.rigGroups[5]")
        pm.connectAttr(animNodes_set.attr("message"), "rig.rigGroups[6]")

    # create dagPose
    pm.select(ctlSet)
    o_node = pm.dagPose(save=True, selection=True)
    pm.connectAttr(o_node.message, rig.rigPoses[0])

    return rig
Exemplo n.º 10
0
    def addCtl(self,
               parent,
               name,
               m,
               color,
               iconShape,
               tp=None,
               lp=True,
               mirrorConf=[0, 0, 0, 0, 0, 0, 0, 0, 0],
               **kwargs):
        """
        Create the control and apply the shape, if this is alrealdy stored
        in the guide controllers grp.

        Args:
            parent (dagNode): The control parent
            name (str): The control name.
            m (matrix): The transfromation matrix for the control.
            color (int or list of float): The color for the control in index or
                RGB.
            iconShape (str): The controls default shape.
            tp (dagNode): Tag Parent Control object to connect as a parent
                controller
            lp (bool): Lock the parent controller channels
            kwargs (variant): Other arguments for the iconShape type variations

        Returns:
            dagNode: The Control.

        """
        if "degree" not in kwargs.keys():
            kwargs["degree"] = 1

        fullName = self.getName(name)
        bufferName = fullName + "_controlBuffer"
        if bufferName in self.rig.guide.controllers.keys():
            ctl_ref = self.rig.guide.controllers[bufferName]
            ctl = primitive.addTransform(parent, fullName, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
                pm.rename(shape, fullName + "Shape")
            icon.setcolor(ctl, color)
        else:
            ctl = icon.create(parent, fullName, m, color, iconShape, **kwargs)

        # create the attributes to handlde mirror and symetrical pose
        attribute.add_mirror_config_channels(ctl, mirrorConf)

        if self.settings["ctlGrp"]:
            ctlGrp = self.settings["ctlGrp"]
            self.addToGroup(ctl, ctlGrp, "controllers")
        else:
            ctlGrp = "controllers"
            self.addToGroup(ctl, ctlGrp)

        # lock the control parent attributes if is not a control
        if parent not in self.groups[ctlGrp] and lp:
            self.transform2Lock.append(parent)

        # Set the control shapes isHistoricallyInteresting
        for oShape in ctl.getShapes():
            oShape.isHistoricallyInteresting.set(False)

        # set controller tag
        if versions.current() >= 201650:
            try:
                oldTag = pm.PyNode(ctl.name() + "_tag")
                if not oldTag.controllerObject.connections():
                    # NOTE:  The next line is comment out. Because this will
                    # happend alot since maya does't clean
                    # controller tags after deleting the control Object of the
                    # tag. This have been log to Autodesk.
                    # If orphane tags are found, it will be clean in silence.
                    # pm.displayWarning("Orphane Tag: %s  will be delete and
                    # created new for: %s"%(oldTag.name(), ctl.name()))
                    pm.delete(oldTag)

            except TypeError:
                pass

            self.add_controller_tag(ctl, tp)

        return ctl
Exemplo n.º 11
0
def lipsRig(eLoop,
            upVertex,
            lowVertex,
            namePrefix,
            thickness,
            doSkin,
            rigidLoops,
            falloffLoops,
            headJnt=None,
            jawJnt=None,
            parent=None,
            ctlName="ctl"):

    ######
    # Var
    ######

    FRONT_OFFSET = .02
    NB_ROPE = 15

    ##################
    # Helper functions
    ##################
    def setName(name, side="C", idx=None):
        namesList = [namePrefix, side, name]
        if idx is not None:
            namesList[1] = side + str(idx)
        name = "_".join(namesList)
        return name

    ###############
    # Checkers
    ##############

    # Loop
    if eLoop:
        try:
            eLoop = [pm.PyNode(e) for e in eLoop.split(",")]
        except pm.MayaNodeError:
            pm.displayWarning(
                "Some of the edges listed in edge loop can not be found")
            return
    else:
        pm.displayWarning("Please set the edge loop first")
        return

    # Vertex
    if upVertex:
        try:
            upVertex = pm.PyNode(upVertex)
        except pm.MayaNodeError:
            pm.displayWarning("%s can not be found" % upVertex)
            return
    else:
        pm.displayWarning("Please set the upper lip central vertex")
        return

    if lowVertex:
        try:
            lowVertex = pm.PyNode(lowVertex)
        except pm.MayaNodeError:
            pm.displayWarning("%s can not be found" % lowVertex)
            return
    else:
        pm.displayWarning("Please set the lower lip central vertex")
        return

    # skinnign data
    if doSkin:
        if not headJnt:
            pm.displayWarning("Please set the Head Jnt or unCheck Compute "
                              "Topological Autoskin")
            return
        else:
            try:
                headJnt = pm.PyNode(headJnt)
            except pm.MayaNodeError:
                pm.displayWarning("Head Joint: %s can not be found" % headJnt)
                return
        if not jawJnt:
            pm.displayWarning("Please set the Jaw Jnt or unCheck Compute "
                              "Topological Autoskin")
            return
        else:
            try:
                jawJnt = pm.PyNode(jawJnt)
            except pm.MayaNodeError:
                pm.displayWarning("Jaw Joint: %s can not be found" % jawJnt)
                return
    # check if the rig already exist in the current scene
    if pm.ls(setName("root")):
        pm.displayWarning("The object %s already exist in the scene. Please "
                          "choose another name prefix" % setName("root"))
        return

    #####################
    # Root creation
    #####################
    lips_root = primitive.addTransform(None, setName("root"))
    lipsCrv_root = primitive.addTransform(lips_root, setName("crvs"))
    lipsRope_root = primitive.addTransform(lips_root, setName("rope"))

    #####################
    # Geometry
    #####################
    geo = pm.listRelatives(eLoop[0], parent=True)[0]

    #####################
    # Groups
    #####################
    try:
        ctlSet = pm.PyNode("rig_controllers_grp")
    except pm.MayaNodeError:
        pm.sets(n="rig_controllers_grp", em=True)
        ctlSet = pm.PyNode("rig_controllers_grp")
    try:
        defset = pm.PyNode("rig_deformers_grp")
    except pm.MayaNodeError:
        pm.sets(n="rig_deformers_grp", em=True)
        defset = pm.PyNode("rig_deformers_grp")

    #####################
    # Curves creation
    #####################

    # get extreme position using the outer loop
    extr_v = meshNavigation.getExtremeVertexFromLoop(eLoop)
    upPos = extr_v[0]
    lowPos = extr_v[1]
    inPos = extr_v[2]
    outPos = extr_v[3]
    edgeList = extr_v[4]
    vertexList = extr_v[5]
    upPos = upVertex
    lowPos = lowVertex

    # upper crv
    upLip_edgeRange = meshNavigation.edgeRangeInLoopFromMid(
        edgeList, upPos, inPos, outPos)
    upCrv = curve.createCuveFromEdges(upLip_edgeRange,
                                      setName("upperLip"),
                                      parent=lipsCrv_root)
    # store the closest vertex by curv cv index. To be use fo the auto skining
    upLip_closestVtxList = []
    # offset upper lip Curve
    cvs = upCrv.getCVs(space="world")
    for i, cv in enumerate(cvs):

        closestVtx = meshNavigation.getClosestVertexFromTransform(geo, cv)
        upLip_closestVtxList.append(closestVtx)
        if i == 0:
            # we know the curv starts from right to left
            offset = [cv[0] - thickness, cv[1], cv[2] - thickness]
        elif i == len(cvs) - 1:
            offset = [cv[0] + thickness, cv[1], cv[2] - thickness]
        else:
            offset = [cv[0], cv[1] + thickness, cv[2]]
        upCrv.setCV(i, offset, space='world')

    # lower crv
    lowLip_edgeRange = meshNavigation.edgeRangeInLoopFromMid(
        edgeList, lowPos, inPos, outPos)
    lowCrv = curve.createCuveFromEdges(lowLip_edgeRange,
                                       setName("lowerLip"),
                                       parent=lipsCrv_root)
    lowLip_closestVtxList = []
    # offset lower lip Curve
    cvs = lowCrv.getCVs(space="world")
    for i, cv in enumerate(cvs):
        closestVtx = meshNavigation.getClosestVertexFromTransform(geo, cv)
        lowLip_closestVtxList.append(closestVtx)
        if i == 0:
            # we know the curv starts from right to left
            offset = [cv[0] - thickness, cv[1], cv[2] - thickness]
        elif i == len(cvs) - 1:
            offset = [cv[0] + thickness, cv[1], cv[2] - thickness]
        else:
            # we populate the closest vertext list here to skipt the first
            # and latest point
            offset = [cv[0], cv[1] - thickness, cv[2]]
        lowCrv.setCV(i, offset, space='world')

    upCrv_ctl = curve.createCurveFromCurve(upCrv,
                                           setName("upCrv_%s" % ctlName),
                                           nbPoints=7,
                                           parent=lipsCrv_root)
    lowCrv_ctl = curve.createCurveFromCurve(lowCrv,
                                            setName("lowCrv_%s" % ctlName),
                                            nbPoints=7,
                                            parent=lipsCrv_root)

    upRope = curve.createCurveFromCurve(upCrv,
                                        setName("upRope_crv"),
                                        nbPoints=NB_ROPE,
                                        parent=lipsCrv_root)
    lowRope = curve.createCurveFromCurve(lowCrv,
                                         setName("lowRope_crv"),
                                         nbPoints=NB_ROPE,
                                         parent=lipsCrv_root)

    upCrv_upv = curve.createCurveFromCurve(upCrv,
                                           setName("upCrv_upv"),
                                           nbPoints=7,
                                           parent=lipsCrv_root)
    lowCrv_upv = curve.createCurveFromCurve(lowCrv,
                                            setName("lowCrv_upv"),
                                            nbPoints=7,
                                            parent=lipsCrv_root)

    upRope_upv = curve.createCurveFromCurve(upCrv,
                                            setName("upRope_upv"),
                                            nbPoints=NB_ROPE,
                                            parent=lipsCrv_root)
    lowRope_upv = curve.createCurveFromCurve(lowCrv,
                                             setName("lowRope_upv"),
                                             nbPoints=NB_ROPE,
                                             parent=lipsCrv_root)

    # offset upv curves

    for crv in [upCrv_upv, lowCrv_upv, upRope_upv, lowRope_upv]:
        cvs = crv.getCVs(space="world")
        for i, cv in enumerate(cvs):

            # we populate the closest vertext list here to skipt the first
            # and latest point
            offset = [cv[0], cv[1], cv[2] + FRONT_OFFSET]
            crv.setCV(i, offset, space='world')

    rigCrvs = [
        upCrv, lowCrv, upCrv_ctl, lowCrv_ctl, upRope, lowRope, upCrv_upv,
        lowCrv_upv, upRope_upv, lowRope_upv
    ]

    for crv in rigCrvs:
        crv.attr("visibility").set(False)

    ##################
    # Controls
    ##################

    # Controls lists
    upControls = []
    upVec = []
    upNpo = []
    lowControls = []
    lowVec = []
    lowNpo = []
    # controls options
    axis_list = ["sx", "sy", "sz", "ro", "rx", "ry", "rz"]
    upCtlOptions = [["corner", "R", "square", 4, .05, axis_list],
                    ["upOuter", "R", "circle", 14, .03, []],
                    ["upInner", "R", "circle", 14, .03, []],
                    ["upper", "C", "square", 4, .05, axis_list],
                    ["upInner", "L", "circle", 14, .03, []],
                    ["upOuter", "L", "circle", 14, .03, []],
                    ["corner", "L", "square", 4, .05, axis_list]]

    lowCtlOptions = [["lowOuter", "R", "circle", 14, .03, []],
                     ["lowInner", "R", "circle", 14, .03, []],
                     ["lower", "C", "square", 4, .05, axis_list],
                     ["lowInner", "L", "circle", 14, .03, []],
                     ["lowOuter", "L", "circle", 14, .03, []]]

    params = ["tx", "ty", "tz"]

    # upper controls
    cvs = upCrv_ctl.getCVs(space="world")
    pm.progressWindow(title='Upper controls', progress=0, max=len(cvs))

    v0 = transform.getTransformFromPos(cvs[0])
    v1 = transform.getTransformFromPos(cvs[-1])
    distSize = vector.getDistance(v0, v1) * 3
    # print distSize

    for i, cv in enumerate(cvs):
        pm.progressWindow(e=True,
                          step=1,
                          status='\nCreating control for%s' % cv)
        t = transform.getTransformFromPos(cv)

        oName = upCtlOptions[i][0]
        oSide = upCtlOptions[i][1]
        o_icon = upCtlOptions[i][2]
        color = upCtlOptions[i][3]
        wd = upCtlOptions[i][4]
        oPar = upCtlOptions[i][5]
        npo = primitive.addTransform(lips_root,
                                     setName("%s_npo" % oName, oSide), t)
        upNpo.append(npo)
        ctl = icon.create(npo,
                          setName("%s_%s" % (oName, ctlName), oSide),
                          t,
                          icon=o_icon,
                          w=wd * distSize,
                          d=wd * distSize,
                          ro=datatypes.Vector(1.57079633, 0, 0),
                          po=datatypes.Vector(0, 0, .07 * distSize),
                          color=color)

        upControls.append(ctl)
        if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl)
        attribute.setKeyableAttributes(ctl, params + oPar)

        upv = primitive.addTransform(ctl, setName("%s_upv" % oName, oSide), t)
        upv.attr("tz").set(FRONT_OFFSET)
        upVec.append(upv)
        if oSide == "R":
            npo.attr("sx").set(-1)
    pm.progressWindow(e=True, endProgress=True)

    # lower controls
    cvs = lowCrv_ctl.getCVs(space="world")
    pm.progressWindow(title='Lower controls', progress=0, max=len(cvs))

    for i, cv in enumerate(cvs[1:-1]):
        pm.progressWindow(e=True,
                          step=1,
                          status='\nCreating control for%s' % cv)

        t = transform.getTransformFromPos(cv)

        oName = lowCtlOptions[i][0]
        oSide = lowCtlOptions[i][1]
        o_icon = lowCtlOptions[i][2]
        color = lowCtlOptions[i][3]
        wd = lowCtlOptions[i][4]
        oPar = lowCtlOptions[i][5]
        npo = primitive.addTransform(lips_root,
                                     setName("%s_npo" % oName, oSide), t)
        lowNpo.append(npo)
        ctl = icon.create(npo,
                          setName("%s_%s" % (oName, ctlName), oSide),
                          t,
                          icon=o_icon,
                          w=wd * distSize,
                          d=wd * distSize,
                          ro=datatypes.Vector(1.57079633, 0, 0),
                          po=datatypes.Vector(0, 0, .07 * distSize),
                          color=color)
        lowControls.append(ctl)
        if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl)
        attribute.setKeyableAttributes(ctl, params + oPar)

        upv = primitive.addTransform(ctl, setName("%s_upv" % oName, oSide), t)
        upv.attr("tz").set(FRONT_OFFSET)
        lowVec.append(upv)
        if oSide == "R":
            npo.attr("sx").set(-1)
    pm.progressWindow(e=True, endProgress=True)

    # reparentig controls
    pm.parent(upNpo[1], lowNpo[0], upControls[0])
    pm.parent(upNpo[2], upNpo[4], upControls[3])
    pm.parent(upNpo[-2], lowNpo[-1], upControls[-1])
    pm.parent(lowNpo[1], lowNpo[3], lowControls[2])

    # Connecting control crvs with controls
    applyop.gear_curvecns_op(upCrv_ctl, upControls)
    applyop.gear_curvecns_op(lowCrv_ctl,
                             [upControls[0]] + lowControls + [upControls[-1]])

    applyop.gear_curvecns_op(upCrv_upv, upVec)
    applyop.gear_curvecns_op(lowCrv_upv, [upVec[0]] + lowVec + [upVec[-1]])

    # adding wires
    pm.wire(upCrv, w=upCrv_ctl)
    pm.wire(lowCrv, w=lowCrv_ctl)
    pm.wire(upRope, w=upCrv_ctl)
    pm.wire(lowRope, w=lowCrv_ctl)

    pm.wire(upRope_upv, w=upCrv_upv)
    pm.wire(lowRope_upv, w=lowCrv_upv)

    # setting constrains
    # up
    cns_node = pm.parentConstraint(upControls[0],
                                   upControls[3],
                                   upControls[1].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(upControls[0].name() + "W0").set(.75)
    cns_node.attr(upControls[3].name() + "W1").set(.25)

    cns_node = pm.parentConstraint(upControls[0],
                                   upControls[3],
                                   upControls[2].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(upControls[0].name() + "W0").set(.25)
    cns_node.attr(upControls[3].name() + "W1").set(.75)

    cns_node = pm.parentConstraint(upControls[3],
                                   upControls[6],
                                   upControls[4].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(upControls[3].name() + "W0").set(.75)
    cns_node.attr(upControls[6].name() + "W1").set(.25)

    cns_node = pm.parentConstraint(upControls[3],
                                   upControls[6],
                                   upControls[5].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(upControls[3].name() + "W0").set(.25)
    cns_node.attr(upControls[6].name() + "W1").set(.75)

    # low
    cns_node = pm.parentConstraint(upControls[0],
                                   lowControls[2],
                                   lowControls[0].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(upControls[0].name() + "W0").set(.75)
    cns_node.attr(lowControls[2].name() + "W1").set(.25)

    cns_node = pm.parentConstraint(upControls[0],
                                   lowControls[2],
                                   lowControls[1].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(upControls[0].name() + "W0").set(.25)
    cns_node.attr(lowControls[2].name() + "W1").set(.75)

    cns_node = pm.parentConstraint(lowControls[2],
                                   upControls[6],
                                   lowControls[3].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(lowControls[2].name() + "W0").set(.75)
    cns_node.attr(upControls[6].name() + "W1").set(.25)

    cns_node = pm.parentConstraint(lowControls[2],
                                   upControls[6],
                                   lowControls[4].getParent(),
                                   mo=True,
                                   skipRotate=["x", "y", "z"])
    cns_node.attr(lowControls[2].name() + "W0").set(.25)
    cns_node.attr(upControls[6].name() + "W1").set(.75)

    ##################
    # Joints
    ##################

    lvlType = "transform"

    # upper joints
    upperJoints = []
    cvs = upCrv.getCVs(space="world")
    pm.progressWindow(title='Creating Upper Joints', progress=0, max=len(cvs))

    for i, cv in enumerate(cvs):
        pm.progressWindow(e=True,
                          step=1,
                          status='\nCreating Joint for  %s' % cv)
        oTransUpV = pm.PyNode(
            pm.createNode(lvlType,
                          n=setName("upLipRopeUpv", idx=str(i).zfill(3)),
                          p=lipsRope_root,
                          ss=True))
        oTrans = pm.PyNode(
            pm.createNode(lvlType,
                          n=setName("upLipRope", idx=str(i).zfill(3)),
                          p=lipsRope_root,
                          ss=True))

        oParam, oLength = curve.getCurveParamAtPosition(upRope, cv)
        uLength = curve.findLenghtFromParam(upRope, oParam)
        u = uLength / oLength

        applyop.pathCns(oTransUpV,
                        upRope_upv,
                        cnsType=False,
                        u=u,
                        tangent=False)

        cns = applyop.pathCns(oTrans,
                              upRope,
                              cnsType=False,
                              u=u,
                              tangent=False)

        cns.setAttr("worldUpType", 1)
        cns.setAttr("frontAxis", 0)
        cns.setAttr("upAxis", 1)

        pm.connectAttr(oTransUpV.attr("worldMatrix[0]"),
                       cns.attr("worldUpMatrix"))

        # getting joint parent
        if headJnt and isinstance(headJnt, str):
            try:
                j_parent = pm.PyNode(headJnt)
            except pm.MayaNodeError:
                j_parent = False
        elif headJnt and isinstance(headJnt, pm.PyNode):
            j_parent = headJnt
        else:
            j_parent = False

        jnt = rigbits.addJnt(oTrans, noReplace=True, parent=j_parent)
        upperJoints.append(jnt)
        pm.sets(defset, add=jnt)
    pm.progressWindow(e=True, endProgress=True)

    # lower joints
    lowerJoints = []
    cvs = lowCrv.getCVs(space="world")
    pm.progressWindow(title='Creating Lower Joints', progress=0, max=len(cvs))

    for i, cv in enumerate(cvs):
        pm.progressWindow(e=True,
                          step=1,
                          status='\nCreating Joint for  %s' % cv)
        oTransUpV = pm.PyNode(
            pm.createNode(lvlType,
                          n=setName("lowLipRopeUpv", idx=str(i).zfill(3)),
                          p=lipsRope_root,
                          ss=True))

        oTrans = pm.PyNode(
            pm.createNode(lvlType,
                          n=setName("lowLipRope", idx=str(i).zfill(3)),
                          p=lipsRope_root,
                          ss=True))

        oParam, oLength = curve.getCurveParamAtPosition(lowRope, cv)
        uLength = curve.findLenghtFromParam(lowRope, oParam)
        u = uLength / oLength

        applyop.pathCns(oTransUpV,
                        lowRope_upv,
                        cnsType=False,
                        u=u,
                        tangent=False)
        cns = applyop.pathCns(oTrans,
                              lowRope,
                              cnsType=False,
                              u=u,
                              tangent=False)

        cns.setAttr("worldUpType", 1)
        cns.setAttr("frontAxis", 0)
        cns.setAttr("upAxis", 1)

        pm.connectAttr(oTransUpV.attr("worldMatrix[0]"),
                       cns.attr("worldUpMatrix"))

        # getting joint parent
        if jawJnt and isinstance(jawJnt, str):
            try:
                j_parent = pm.PyNode(jawJnt)
            except pm.MayaNodeError:
                pass
        elif jawJnt and isinstance(jawJnt, pm.PyNode):
            j_parent = jawJnt
        else:
            j_parent = False
        jnt = rigbits.addJnt(oTrans, noReplace=True, parent=j_parent)
        lowerJoints.append(jnt)
        pm.sets(defset, add=jnt)
    pm.progressWindow(e=True, endProgress=True)

    ###########################################
    # Connecting rig
    ###########################################
    if parent:
        try:
            if isinstance(parent, basestring):
                parent = pm.PyNode(parent)
            parent.addChild(lips_root)
        except pm.MayaNodeError:
            pm.displayWarning("The Lips rig can not be parent to: %s. Maybe "
                              "this object doesn't exist." % parent)
    if headJnt and jawJnt:
        try:
            if isinstance(headJnt, basestring):
                headJnt = pm.PyNode(headJnt)
        except pm.MayaNodeError:
            pm.displayWarning("Head Joint or Upper Lip Joint %s. Can not be "
                              "fount in the scene" % headJnt)
            return
        try:
            if isinstance(jawJnt, basestring):
                jawJnt = pm.PyNode(jawJnt)
        except pm.MayaNodeError:
            pm.displayWarning("Jaw Joint or Lower Lip Joint %s. Can not be "
                              "fount in the scene" % jawJnt)
            return

        # right corner connection
        pm.parentConstraint(headJnt,
                            jawJnt,
                            upControls[0].getParent(),
                            mo=True)
        # left corner connection
        pm.parentConstraint(headJnt,
                            jawJnt,
                            upControls[-1].getParent(),
                            mo=True)
        # up control connection
        pm.parentConstraint(headJnt, upControls[3].getParent(), mo=True)
        # low control connection
        pm.parentConstraint(jawJnt, lowControls[2].getParent(), mo=True)

    ###########################################
    # Auto Skinning
    ###########################################
    if doSkin:
        # eyelid vertex rows
        totalLoops = rigidLoops + falloffLoops
        vertexLoopList = meshNavigation.getConcentricVertexLoop(
            vertexList, totalLoops)
        vertexRowList = meshNavigation.getVertexRowsFromLoops(vertexLoopList)

        # we set the first value 100% for the first initial loop
        skinPercList = [1.0]
        # we expect to have a regular grid topology
        for r in range(rigidLoops):
            for rr in range(2):
                skinPercList.append(1.0)
        increment = 1.0 / float(falloffLoops)
        # we invert to smooth out from 100 to 0
        inv = 1.0 - increment
        for r in range(falloffLoops):
            for rr in range(2):
                if inv < 0.0:
                    inv = 0.0
                skinPercList.append(inv)
            inv -= increment

        # this loop add an extra 0.0 indices to avoid errors
        for r in range(10):
            for rr in range(2):
                skinPercList.append(0.0)

        # base skin
        if headJnt:
            try:
                headJnt = pm.PyNode(headJnt)
            except pm.MayaNodeError:
                pm.displayWarning("Auto skin aborted can not find %s " %
                                  headJnt)
                return

        # Check if the object has a skinCluster
        objName = pm.listRelatives(geo, parent=True)[0]

        skinCluster = skin.getSkinCluster(objName)
        if not skinCluster:
            skinCluster = pm.skinCluster(headJnt,
                                         geo,
                                         tsb=True,
                                         nw=2,
                                         n='skinClsEyelid')

        lipsJoints = upperJoints + lowerJoints
        closestVtxList = upLip_closestVtxList + lowLip_closestVtxList
        pm.progressWindow(title='Auto skinning process',
                          progress=0,
                          max=len(lipsJoints))

        for i, jnt in enumerate(lipsJoints):
            pm.progressWindow(e=True, step=1, status='\nSkinning %s' % jnt)
            skinCluster.addInfluence(jnt, weight=0)
            v = closestVtxList[i]
            for row in vertexRowList:
                if v in row:
                    for i, rv in enumerate(row):
                        # find the deformer with max value for each vertex
                        w = pm.skinPercent(skinCluster,
                                           rv,
                                           query=True,
                                           value=True)
                        transJoint = pm.skinPercent(skinCluster,
                                                    rv,
                                                    query=True,
                                                    t=None)
                        max_value = max(w)
                        max_index = w.index(max_value)

                        perc = skinPercList[i]
                        t_value = [(jnt, perc),
                                   (transJoint[max_index], 1.0 - perc)]
                        pm.skinPercent(skinCluster, rv, transformValue=t_value)
        pm.progressWindow(e=True, endProgress=True)
Exemplo n.º 12
0
def cycleTweak(name,
               edgePair,
               mirrorAxis,
               baseMesh,
               rotMesh,
               transMesh,
               setupParent,
               ctlParent,
               jntOrg=None,
               grp=None,
               iconType="square",
               size=.025,
               color=13,
               ro=datatypes.Vector(1.5708, 0, 1.5708 / 2)):
    """The command to create a cycle tweak.

    A cycle tweak is a tweak that cycles to the parent position but doesn't
    create a cycle of dependency. This type of tweaks
    are very useful to create facial tweakers.

    Args:
        name (string): Name for the cycle tweak
        edgePair (list): List of edge pair to attach the cycle tweak
        mirrorAxis (bool): If true, will mirror the x axis behaviour.
        baseMesh (Mesh): The base mesh for the cycle tweak.
        rotMesh (Mesh): The mesh that will support the rotation transformations
                for the cycle tweak
        transMesh (Mesh): The mesh that will support the translation and scale
                transformations for the cycle tweak
        setupParent (dagNode): The parent for the setup objects
        ctlParent (dagNode): The parent for the control objects
        jntOrg (None or dagNode, optional): The parent for the joints
        grp (None or set, optional): The set to add the controls
        iconType (str, optional): The controls shape
        size (float, optional): The control size
        color (int, optional): The control color
        ro (TYPE, optional): The control shape rotation offset

    Returns:
        multi: the tweak control and the list of related joints.
    """
    # rotation sctructure
    rRivet = rivet.rivet()
    rBase = rRivet.create(baseMesh, edgePair[0], edgePair[1], setupParent,
                          name + "_rRivet_loc")

    pos = rBase.getTranslation(space="world")

    # translation structure
    tRivetParent = pm.createNode("transform",
                                 n=name + "_tRivetBase",
                                 p=ctlParent)
    tRivetParent.setMatrix(datatypes.Matrix(), worldSpace=True)
    tRivet = rivet.rivet()
    tBase = tRivet.create(transMesh, edgePair[0], edgePair[1], tRivetParent,
                          name + "_tRivet_loc")

    # create the control
    tweakBase = pm.createNode("transform", n=name + "_tweakBase", p=ctlParent)
    tweakBase.setMatrix(datatypes.Matrix(), worldSpace=True)
    tweakNpo = pm.createNode("transform", n=name + "_tweakNpo", p=tweakBase)
    tweakBase.setTranslation(pos, space="world")
    tweakCtl = icon.create(tweakNpo,
                           name + "_ctl",
                           tweakNpo.getMatrix(worldSpace=True),
                           color,
                           iconType,
                           w=size,
                           d=size,
                           ro=ro)
    inverseTranslateParent(tweakCtl)
    pm.pointConstraint(tBase, tweakBase)

    # rot
    rotBase = pm.createNode("transform", n=name + "_rotBase", p=setupParent)
    rotBase.setMatrix(datatypes.Matrix(), worldSpace=True)
    rotNPO = pm.createNode("transform", n=name + "_rot_npo", p=rotBase)
    rotJointDriver = pm.createNode("transform",
                                   n=name + "_rotJointDriver",
                                   p=rotNPO)
    rotBase.setTranslation(pos, space="world")

    node.createMulNode(
        [rotNPO.attr("tx"),
         rotNPO.attr("ty"),
         rotNPO.attr("tz")], [-1, -1, -1], [
             rotJointDriver.attr("tx"),
             rotJointDriver.attr("ty"),
             rotJointDriver.attr("tz")
         ])

    pm.pointConstraint(rBase, rotNPO)
    pm.connectAttr(tweakCtl.r, rotNPO.r)
    pm.connectAttr(tweakCtl.s, rotNPO.s)

    # transform
    posNPO = pm.createNode("transform", n=name + "_pos_npo", p=setupParent)
    posJointDriver = pm.createNode("transform",
                                   n=name + "_posJointDriver",
                                   p=posNPO)
    posNPO.setTranslation(pos, space="world")
    pm.connectAttr(tweakCtl.t, posJointDriver.t)

    # mirror behaviour
    if mirrorAxis:
        tweakBase.attr("ry").set(tweakBase.attr("ry").get() + 180)
        rotBase.attr("ry").set(rotBase.attr("ry").get() + 180)
        posNPO.attr("ry").set(posNPO.attr("ry").get() + 180)
        tweakBase.attr("sz").set(-1)
        rotBase.attr("sz").set(-1)
        posNPO.attr("sz").set(-1)

    # create joints
    rJoint = rigbits.addJnt(rotJointDriver, jntOrg, True, grp)
    tJoint = rigbits.addJnt(posJointDriver, jntOrg, True, grp)

    # add to rotation skin
    # TODO: add checker to see if joint is in the skincluster.
    rSK = skin.getSkinCluster(rotMesh)
    pm.skinCluster(rSK, e=True, ai=rJoint, lw=True, wt=0)

    # add to transform skin
    # TODO: add checker to see if joint is in the skincluster.
    tSK = skin.getSkinCluster(transMesh)
    pm.skinCluster(tSK, e=True, ai=tJoint, lw=True, wt=0)

    return tweakCtl, [rJoint, tJoint]
Exemplo n.º 13
0
def eyeRig(eyeMesh,
           edgeLoop,
           blinkH,
           namePrefix,
           offset,
           rigidLoops,
           falloffLoops,
           headJnt,
           doSkin,
           parent=None,
           ctlName="ctl",
           sideRange=False,
           customCorner=False,
           intCorner=None,
           extCorner=None,
           ctlGrp=None,
           defGrp=None):

    """Create eyelid and eye rig

    Args:
        eyeMesh (TYPE): Description
        edgeLoop (TYPE): Description
        blinkH (TYPE): Description
        namePrefix (TYPE): Description
        offset (TYPE): Description
        rigidLoops (TYPE): Description
        falloffLoops (TYPE): Description
        headJnt (TYPE): Description
        doSkin (TYPE): Description
        parent (None, optional): Description
        ctlName (str, optional): Description
        sideRange (bool, optional): Description
        customCorner (bool, optional): Description
        intCorner (None, optional): Description
        extCorner (None, optional): Description
        ctlGrp (None, optional): Description
        defGrp (None, optional): Description

    Returns:
        TYPE: Description
    """
    # Checkers
    if edgeLoop:
        edgeLoopList = [pm.PyNode(e) for e in edgeLoop.split(",")]
    else:
        pm.displayWarning("Please set the edge loop first")
        return

    if eyeMesh:
        try:
            eyeMesh = pm.PyNode(eyeMesh)
        except pm.MayaNodeError:
            pm.displayWarning("The object %s can not be found in the "
                              "scene" % (eyeMesh))
            return
    else:
        pm.displayWarning("Please set the eye mesh first")

    if doSkin:
        if not headJnt:
            pm.displayWarning("Please set the Head Jnt or unCheck "
                              "Compute Topological Autoskin")
            return

    # Initial Data
    bboxCenter = meshNavigation.bboxCenter(eyeMesh)

    extr_v = meshNavigation.getExtremeVertexFromLoop(edgeLoopList, sideRange)
    upPos = extr_v[0]
    lowPos = extr_v[1]
    inPos = extr_v[2]
    outPos = extr_v[3]
    edgeList = extr_v[4]
    vertexList = extr_v[5]

    # Detect the side L or R from the x value
    if inPos.getPosition(space='world')[0] < 0.0:
        side = "R"
        inPos = extr_v[3]
        outPos = extr_v[2]
        normalPos = outPos
        npw = normalPos.getPosition(space='world')
        normalVec = npw - bboxCenter
    else:
        side = "L"
        normalPos = outPos
        npw = normalPos.getPosition(space='world')
        normalVec = bboxCenter - npw
    # Manual Vertex corners
    if customCorner:
        if intCorner:
            try:
                if side == "R":
                    inPos = pm.PyNode(extCorner)
                else:
                    inPos = pm.PyNode(intCorner)
            except pm.MayaNodeError:
                pm.displayWarning("%s can not be found" % intCorner)
                return
        else:
            pm.displayWarning("Please set the internal eyelid corner")
            return

        if extCorner:
            try:
                normalPos = pm.PyNode(extCorner)
                npw = normalPos.getPosition(space='world')
                if side == "R":
                    outPos = pm.PyNode(intCorner)
                    normalVec = npw - bboxCenter
                else:
                    outPos = pm.PyNode(extCorner)
                    normalVec = bboxCenter - npw
            except pm.MayaNodeError:
                pm.displayWarning("%s can not be found" % extCorner)
                return
        else:
            pm.displayWarning("Please set the external eyelid corner")
            return

    # Check if we have prefix:
    if namePrefix:
        namePrefix = string.removeInvalidCharacter(namePrefix)
    else:
        pm.displayWarning("Prefix is needed")
        return

    def setName(name, ind=None):
        namesList = [namePrefix, side, name]
        if ind is not None:
            namesList[1] = side + str(ind)
        name = "_".join(namesList)
        return name

    if pm.ls(setName("root")):
        pm.displayWarning("The object %s already exist in the scene. Please "
                          "choose another name prefix" % setName("root"))
        return

    # Eye root
    eye_root = primitive.addTransform(None, setName("root"))
    eyeCrv_root = primitive.addTransform(eye_root, setName("crvs"))

    # Eyelid Main crvs
    try:
        upEyelid = meshNavigation.edgeRangeInLoopFromMid(
            edgeList, upPos, inPos, outPos)
        upCrv = curve.createCurveFromOrderedEdges(
            upEyelid, inPos, setName("upperEyelid"), parent=eyeCrv_root)
        upCrv_ctl = curve.createCurveFromOrderedEdges(
            upEyelid, inPos, setName("upCrv_%s" % ctlName), parent=eyeCrv_root)
        pm.rebuildCurve(upCrv_ctl, s=2, rt=0, rpo=True, ch=False)

        lowEyelid = meshNavigation.edgeRangeInLoopFromMid(
            edgeList, lowPos, inPos, outPos)
        lowCrv = curve.createCurveFromOrderedEdges(
            lowEyelid, inPos, setName("lowerEyelid"), parent=eyeCrv_root)
        lowCrv_ctl = curve.createCurveFromOrderedEdges(
            lowEyelid,
            inPos,
            setName("lowCrv_%s" % ctlName),
            parent=eyeCrv_root)

        pm.rebuildCurve(lowCrv_ctl, s=2, rt=0, rpo=True, ch=False)

    except UnboundLocalError:
        if customCorner:
            pm.displayWarning("This error is maybe caused because the custom "
                              "Corner vertex is not part of the edge loop")
        pm.displayError(traceback.format_exc())
        return

    upBlink = curve.createCurveFromCurve(
        upCrv, setName("upblink_crv"), nbPoints=30, parent=eyeCrv_root)
    lowBlink = curve.createCurveFromCurve(
        lowCrv, setName("lowBlink_crv"), nbPoints=30, parent=eyeCrv_root)

    upTarget = curve.createCurveFromCurve(
        upCrv, setName("upblink_target"), nbPoints=30, parent=eyeCrv_root)
    lowTarget = curve.createCurveFromCurve(
        lowCrv, setName("lowBlink_target"), nbPoints=30, parent=eyeCrv_root)
    midTarget = curve.createCurveFromCurve(
        lowCrv, setName("midBlink_target"), nbPoints=30, parent=eyeCrv_root)

    rigCrvs = [upCrv,
               lowCrv,
               upCrv_ctl,
               lowCrv_ctl,
               upBlink,
               lowBlink,
               upTarget,
               lowTarget,
               midTarget]

    for crv in rigCrvs:
        crv.attr("visibility").set(False)

    # localBBOX
    localBBox = eyeMesh.getBoundingBox(invisible=True, space='world')
    wRadius = abs((localBBox[0][0] - localBBox[1][0]))
    dRadius = abs((localBBox[0][1] - localBBox[1][1]) / 1.7)

    # Groups
    if not ctlGrp:
        ctlGrp = "rig_controllers_grp"
    try:
        ctlSet = pm.PyNode(ctlGrp)
    except pm.MayaNodeError:
        pm.sets(n=ctlGrp, em=True)
        ctlSet = pm.PyNode(ctlGrp)
    if not defGrp:
        defGrp = "rig_deformers_grp"
    try:
        defset = pm.PyNode(defGrp)
    except pm.MayaNodeError:
        pm.sets(n=defGrp, em=True)
        defset = pm.PyNode(defGrp)

    # Calculate center looking at
    averagePosition = ((upPos.getPosition(space='world')
                        + lowPos.getPosition(space='world')
                        + inPos.getPosition(space='world')
                        + outPos.getPosition(space='world'))
                       / 4)
    if side == "R":
        negate = False
        offset = offset
        over_offset = dRadius
    else:
        negate = False
        over_offset = dRadius

    if side == "R" and sideRange or side == "R" and customCorner:
        axis = "z-x"
        # axis = "zx"
    else:
        axis = "z-x"

    t = transform.getTransformLookingAt(
        bboxCenter,
        averagePosition,
        normalVec,
        axis=axis,
        negate=negate)

    over_npo = primitive.addTransform(
        eye_root, setName("center_lookatRoot"), t)

    over_ctl = icon.create(over_npo,
                           setName("over_%s" % ctlName),
                           t,
                           icon="square",
                           w=wRadius,
                           d=dRadius,
                           ro=datatypes.Vector(1.57079633, 0, 0),
                           po=datatypes.Vector(0, 0, over_offset),
                           color=4)
    node.add_controller_tag(over_ctl)
    attribute.add_mirror_config_channels(over_ctl)
    attribute.setKeyableAttributes(
        over_ctl,
        params=["tx", "ty", "tz", "ro", "rx", "ry", "rz", "sx", "sy", "sz"])

    if side == "R":
        over_npo.attr("rx").set(over_npo.attr("rx").get() * -1)
        over_npo.attr("ry").set(over_npo.attr("ry").get() + 180)
        over_npo.attr("sz").set(-1)

    if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
        pass
    else:
        pm.sets(ctlSet, add=over_ctl)

    center_lookat = primitive.addTransform(
        over_ctl, setName("center_lookat"), t)

    # Tracking
    # Eye aim control
    t_arrow = transform.getTransformLookingAt(bboxCenter,
                                              averagePosition,
                                              upPos.getPosition(space='world'),
                                              axis="zy", negate=False)

    radius = abs((localBBox[0][0] - localBBox[1][0]) / 1.7)
    arrow_npo = primitive.addTransform(eye_root, setName("aim_npo"), t_arrow)
    arrow_ctl = icon.create(arrow_npo,
                            setName("aim_%s" % ctlName),
                            t_arrow,
                            icon="arrow",
                            w=1,
                            po=datatypes.Vector(0, 0, radius),
                            color=4)
    if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
        pass
    else:
        pm.sets(ctlSet, add=arrow_ctl)
    attribute.setKeyableAttributes(arrow_ctl, params=["rx", "ry", "rz"])

    # tracking custom trigger
    if side == "R":
        tt = t_arrow
    else:
        tt = t
    aimTrigger_root = primitive.addTransform(
        center_lookat, setName("aimTrigger_root"), tt)
    aimTrigger_lvl = primitive.addTransform(
        aimTrigger_root, setName("aimTrigger_lvl"), tt)
    aimTrigger_lvl.attr("tz").set(1.0)
    aimTrigger_ref = primitive.addTransform(
        aimTrigger_lvl, setName("aimTrigger_ref"), tt)
    aimTrigger_ref.attr("tz").set(0.0)
    # connect  trigger with arrow_ctl
    pm.parentConstraint(arrow_ctl, aimTrigger_ref, mo=True)

    # Controls lists
    upControls = []
    trackLvl = []

    # upper eyelid controls
    upperCtlNames = ["inCorner", "upInMid", "upMid", "upOutMid", "outCorner"]
    cvs = upCrv_ctl.getCVs(space="world")
    if side == "R" and not sideRange:
        # if side == "R":
        cvs = [cv for cv in reversed(cvs)]
    for i, cv in enumerate(cvs):
        if utils.is_odd(i):
            color = 14
            wd = .5
            icon_shape = "circle"
            params = ["tx", "ty", "tz"]
        else:
            color = 4
            wd = .7
            icon_shape = "square"
            params = ["tx",
                      "ty",
                      "tz",
                      "ro",
                      "rx",
                      "ry",
                      "rz",
                      "sx",
                      "sy",
                      "sz"]

        t = transform.setMatrixPosition(t, cvs[i])
        npo = primitive.addTransform(center_lookat,
                                     setName("%s_npo" % upperCtlNames[i]),
                                     t)
        npoBase = npo
        if i == 2:
            # we add an extra level to input the tracking ofset values
            npo = primitive.addTransform(npo,
                                         setName("%s_trk" % upperCtlNames[i]),
                                         t)
            trackLvl.append(npo)

        ctl = icon.create(npo,
                          setName("%s_%s" % (upperCtlNames[i], ctlName)),
                          t,
                          icon=icon_shape,
                          w=wd,
                          d=wd,
                          ro=datatypes.Vector(1.57079633, 0, 0),
                          po=datatypes.Vector(0, 0, offset),
                          color=color)
        attribute.add_mirror_config_channels(ctl)
        node.add_controller_tag(ctl, over_ctl)
        upControls.append(ctl)
        if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl)
        attribute.setKeyableAttributes(ctl, params)
        if side == "R":
            npoBase.attr("ry").set(180)
            npoBase.attr("sz").set(-1)

    # adding parent average contrains to odd controls
    for i, ctl in enumerate(upControls):
        if utils.is_odd(i):
            pm.parentConstraint(upControls[i - 1],
                                upControls[i + 1],
                                ctl.getParent(),
                                mo=True)

    # lower eyelid controls
    lowControls = [upControls[0]]
    lowerCtlNames = ["inCorner",
                     "lowInMid",
                     "lowMid",
                     "lowOutMid",
                     "outCorner"]

    cvs = lowCrv_ctl.getCVs(space="world")
    if side == "R" and not sideRange:
        cvs = [cv for cv in reversed(cvs)]
    for i, cv in enumerate(cvs):
        # we skip the first and last point since is already in the uper eyelid
        if i in [0, 4]:
            continue
        if utils.is_odd(i):
            color = 14
            wd = .5
            icon_shape = "circle"
            params = ["tx", "ty", "tz"]
        else:
            color = 4
            wd = .7
            icon_shape = "square"
            params = ["tx",
                      "ty",
                      "tz",
                      "ro",
                      "rx",
                      "ry",
                      "rz",
                      "sx",
                      "sy",
                      "sz"]

        t = transform.setMatrixPosition(t, cvs[i])
        npo = primitive.addTransform(center_lookat,
                                     setName("%s_npo" % lowerCtlNames[i]),
                                     t)
        npoBase = npo
        if i == 2:
            # we add an extra level to input the tracking ofset values
            npo = primitive.addTransform(npo,
                                         setName("%s_trk" % lowerCtlNames[i]),
                                         t)
            trackLvl.append(npo)
        ctl = icon.create(npo,
                          setName("%s_%s" % (lowerCtlNames[i], ctlName)),
                          t,
                          icon=icon_shape,
                          w=wd,
                          d=wd,
                          ro=datatypes.Vector(1.57079633, 0, 0),
                          po=datatypes.Vector(0, 0, offset),
                          color=color)
        attribute.add_mirror_config_channels(ctl)

        lowControls.append(ctl)
        if len(ctlName.split("_")) == 2 and ctlName.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl)
        attribute.setKeyableAttributes(ctl, params)
        # mirror behaviout on R side controls
        if side == "R":
            npoBase.attr("ry").set(180)
            npoBase.attr("sz").set(-1)
    for lctl in reversed(lowControls[1:]):
        node.add_controller_tag(lctl, over_ctl)
    lowControls.append(upControls[-1])

    # adding parent average contrains to odd controls
    for i, ctl in enumerate(lowControls):
        if utils.is_odd(i):
            pm.parentConstraint(lowControls[i - 1],
                                lowControls[i + 1],
                                ctl.getParent(),
                                mo=True)

    # Connecting control crvs with controls
    applyop.gear_curvecns_op(upCrv_ctl, upControls)
    applyop.gear_curvecns_op(lowCrv_ctl, lowControls)

    # adding wires
    w1 = pm.wire(upCrv, w=upBlink)[0]
    w2 = pm.wire(lowCrv, w=lowBlink)[0]

    w3 = pm.wire(upTarget, w=upCrv_ctl)[0]
    w4 = pm.wire(lowTarget, w=lowCrv_ctl)[0]

    # adding blendshapes
    bs_upBlink = pm.blendShape(upTarget,
                               midTarget,
                               upBlink,
                               n="blendShapeUpBlink")
    bs_lowBlink = pm.blendShape(lowTarget,
                                midTarget,
                                lowBlink,
                                n="blendShapeLowBlink")
    bs_mid = pm.blendShape(lowTarget,
                           upTarget,
                           midTarget,
                           n="blendShapeLowBlink")

    # setting blendshape reverse connections
    rev_node = pm.createNode("reverse")
    pm.connectAttr(bs_upBlink[0].attr(midTarget.name()), rev_node + ".inputX")
    pm.connectAttr(rev_node + ".outputX", bs_upBlink[0].attr(upTarget.name()))
    rev_node = pm.createNode("reverse")
    pm.connectAttr(bs_lowBlink[0].attr(midTarget.name()), rev_node + ".inputX")
    pm.connectAttr(rev_node + ".outputX",
                   bs_lowBlink[0].attr(lowTarget.name()))
    rev_node = pm.createNode("reverse")
    pm.connectAttr(bs_mid[0].attr(upTarget.name()), rev_node + ".inputX")
    pm.connectAttr(rev_node + ".outputX", bs_mid[0].attr(lowTarget.name()))

    # setting default values
    bs_mid[0].attr(upTarget.name()).set(blinkH)

    # joints root
    jnt_root = primitive.addTransformFromPos(
        eye_root, setName("joints"), pos=bboxCenter)

    # head joint
    if headJnt:
        try:
            headJnt = pm.PyNode(headJnt)
            jnt_base = headJnt
        except pm.MayaNodeError:
            pm.displayWarning(
                "Aborted can not find %s " % headJnt)
            return
    else:
        # Eye root
        jnt_base = jnt_root

    eyeTargets_root = primitive.addTransform(eye_root,
                                             setName("targets"))

    eyeCenter_jnt = rigbits.addJnt(arrow_ctl,
                                   jnt_base,
                                   grp=defset,
                                   jntName=setName("center_jnt"))

    # Upper Eyelid joints ##################################################

    cvs = upCrv.getCVs(space="world")
    upCrv_info = node.createCurveInfoNode(upCrv)

    # aim constrain targets and joints
    upperEyelid_aimTargets = []
    upperEyelid_jnt = []
    upperEyelid_jntRoot = []

    for i, cv in enumerate(cvs):

        # aim targets
        trn = primitive.addTransformFromPos(eyeTargets_root,
                                            setName("upEyelid_aimTarget", i),
                                            pos=cv)
        upperEyelid_aimTargets.append(trn)
        # connecting positions with crv
        pm.connectAttr(upCrv_info + ".controlPoints[%s]" % str(i),
                       trn.attr("translate"))

        # joints
        jntRoot = primitive.addJointFromPos(jnt_root,
                                            setName("upEyelid_jnt_base", i),
                                            pos=bboxCenter)
        jntRoot.attr("radius").set(.08)
        jntRoot.attr("visibility").set(False)
        upperEyelid_jntRoot.append(jntRoot)
        applyop.aimCns(jntRoot, trn, axis="zy", wupObject=jnt_root)

        jnt_ref = primitive.addJointFromPos(jntRoot,
                                            setName("upEyelid_jnt_ref", i),
                                            pos=cv)
        jnt_ref.attr("radius").set(.08)
        jnt_ref.attr("visibility").set(False)

        jnt = rigbits.addJnt(jnt_ref,
                             jnt_base,
                             grp=defset,
                             jntName=setName("upEyelid_jnt", i))
        upperEyelid_jnt.append(jnt)

    # Lower Eyelid joints ##################################################

    cvs = lowCrv.getCVs(space="world")
    lowCrv_info = node.createCurveInfoNode(lowCrv)

    # aim constrain targets and joints
    lowerEyelid_aimTargets = []
    lowerEyelid_jnt = []
    lowerEyelid_jntRoot = []

    for i, cv in enumerate(cvs):
        if i in [0, len(cvs) - 1]:
            continue

        # aim targets
        trn = primitive.addTransformFromPos(eyeTargets_root,
                                            setName("lowEyelid_aimTarget", i),
                                            pos=cv)
        lowerEyelid_aimTargets.append(trn)
        # connecting positions with crv
        pm.connectAttr(lowCrv_info + ".controlPoints[%s]" % str(i),
                       trn.attr("translate"))

        # joints
        jntRoot = primitive.addJointFromPos(jnt_root,
                                            setName("lowEyelid_base", i),
                                            pos=bboxCenter)
        jntRoot.attr("radius").set(.08)
        jntRoot.attr("visibility").set(False)
        lowerEyelid_jntRoot.append(jntRoot)
        applyop.aimCns(jntRoot, trn, axis="zy", wupObject=jnt_root)

        jnt_ref = primitive.addJointFromPos(jntRoot,
                                            setName("lowEyelid_jnt_ref", i),
                                            pos=cv)
        jnt_ref.attr("radius").set(.08)
        jnt_ref.attr("visibility").set(False)

        jnt = rigbits.addJnt(jnt_ref,
                             jnt_base,
                             grp=defset,
                             jntName=setName("lowEyelid_jnt", i))
        lowerEyelid_jnt.append(jnt)

    # Channels
    # Adding and connecting attributes for the blink
    up_ctl = upControls[2]
    blink_att = attribute.addAttribute(
        over_ctl, "blink", "float", 0, minValue=0, maxValue=1)
    blinkMult_att = attribute.addAttribute(
        over_ctl, "blinkMult", "float", 1, minValue=1, maxValue=2)
    midBlinkH_att = attribute.addAttribute(
        over_ctl, "blinkHeight", "float", blinkH, minValue=0, maxValue=1)
    mult_node = node.createMulNode(blink_att, blinkMult_att)
    pm.connectAttr(mult_node + ".outputX",
                   bs_upBlink[0].attr(midTarget.name()))
    pm.connectAttr(mult_node + ".outputX",
                   bs_lowBlink[0].attr(midTarget.name()))
    pm.connectAttr(midBlinkH_att, bs_mid[0].attr(upTarget.name()))

    low_ctl = lowControls[2]

    # Adding channels for eye tracking
    upVTracking_att = attribute.addAttribute(up_ctl,
                                             "vTracking",
                                             "float",
                                             .02,
                                             minValue=0,
                                             maxValue=1,
                                             keyable=False,
                                             channelBox=True)
    upHTracking_att = attribute.addAttribute(up_ctl,
                                             "hTracking",
                                             "float",
                                             .01,
                                             minValue=0,
                                             maxValue=1,
                                             keyable=False,
                                             channelBox=True)

    lowVTracking_att = attribute.addAttribute(low_ctl,
                                              "vTracking",
                                              "float",
                                              .01,
                                              minValue=0,
                                              maxValue=1,
                                              keyable=False,
                                              channelBox=True)
    lowHTracking_att = attribute.addAttribute(low_ctl,
                                              "hTracking",
                                              "float",
                                              .01,
                                              minValue=0,
                                              maxValue=1,
                                              keyable=False,
                                              channelBox=True)

    mult_node = node.createMulNode(upVTracking_att, aimTrigger_ref.attr("ty"))
    pm.connectAttr(mult_node + ".outputX", trackLvl[0].attr("ty"))
    mult_node = node.createMulNode(upHTracking_att, aimTrigger_ref.attr("tx"))
    pm.connectAttr(mult_node + ".outputX", trackLvl[0].attr("tx"))

    mult_node = node.createMulNode(lowVTracking_att, aimTrigger_ref.attr("ty"))
    pm.connectAttr(mult_node + ".outputX", trackLvl[1].attr("ty"))
    mult_node = node.createMulNode(lowHTracking_att, aimTrigger_ref.attr("tx"))
    pm.connectAttr(mult_node + ".outputX", trackLvl[1].attr("tx"))

    # Tension on blink
    node.createReverseNode(blink_att, w1.scale[0])
    node.createReverseNode(blink_att, w3.scale[0])
    node.createReverseNode(blink_att, w2.scale[0])
    node.createReverseNode(blink_att, w4.scale[0])

    ###########################################
    # Reparenting
    ###########################################
    if parent:
        try:
            if isinstance(parent, basestring):
                parent = pm.PyNode(parent)
            parent.addChild(eye_root)
        except pm.MayaNodeError:
            pm.displayWarning("The eye rig can not be parent to: %s. Maybe "
                              "this object doesn't exist." % parent)

    ###########################################
    # Auto Skinning
    ###########################################
    if doSkin:
        # eyelid vertex rows
        totalLoops = rigidLoops + falloffLoops
        vertexLoopList = meshNavigation.getConcentricVertexLoop(vertexList,
                                                                totalLoops)
        vertexRowList = meshNavigation.getVertexRowsFromLoops(vertexLoopList)

        # we set the first value 100% for the first initial loop
        skinPercList = [1.0]
        # we expect to have a regular grid topology
        for r in range(rigidLoops):
            for rr in range(2):
                skinPercList.append(1.0)
        increment = 1.0 / float(falloffLoops)
        # we invert to smooth out from 100 to 0
        inv = 1.0 - increment
        for r in range(falloffLoops):
            for rr in range(2):
                if inv < 0.0:
                    inv = 0.0
                skinPercList.append(inv)
            inv -= increment

        # this loop add an extra 0.0 indices to avoid errors
        for r in range(10):
            for rr in range(2):
                skinPercList.append(0.0)

        # base skin
        geo = pm.listRelatives(edgeLoopList[0], parent=True)[0]
        # Check if the object has a skinCluster
        objName = pm.listRelatives(geo, parent=True)[0]

        skinCluster = skin.getSkinCluster(objName)
        if not skinCluster:
            skinCluster = pm.skinCluster(headJnt,
                                         geo,
                                         tsb=True,
                                         nw=2,
                                         n='skinClsEyelid')

        eyelidJoints = upperEyelid_jnt + lowerEyelid_jnt
        pm.progressWindow(title='Auto skinning process',
                          progress=0,
                          max=len(eyelidJoints))
        firstBoundary = False
        for jnt in eyelidJoints:
            pm.progressWindow(e=True, step=1, status='\nSkinning %s' % jnt)
            skinCluster.addInfluence(jnt, weight=0)
            v = meshNavigation.getClosestVertexFromTransform(geo, jnt)

            for row in vertexRowList:

                if v in row:
                    it = 0  # iterator
                    inc = 1  # increment
                    for i, rv in enumerate(row):
                        try:
                            perc = skinPercList[it]
                            t_val = [(jnt, perc), (headJnt, 1.0 - perc)]
                            pm.skinPercent(skinCluster,
                                           rv,
                                           transformValue=t_val)
                            if rv.isOnBoundary():
                                # we need to compare with the first boundary
                                # to check if the row have inverted direction
                                # and offset the value
                                if not firstBoundary:
                                    firstBoundary = True
                                    firstBoundaryValue = it

                                else:
                                    if it < firstBoundaryValue:
                                        it -= 1
                                    elif it > firstBoundaryValue:
                                        it += 1
                                inc = 2
                        except IndexError:
                            continue

                        it = it + inc
        pm.progressWindow(e=True, endProgress=True)

        # Eye Mesh skinning
        skinCluster = skin.getSkinCluster(eyeMesh)
        if not skinCluster:
            skinCluster = pm.skinCluster(eyeCenter_jnt,
                                         eyeMesh,
                                         tsb=True,
                                         nw=1,
                                         n='skinClsEye')
Exemplo n.º 14
0
    def addCtl(self, parent, name, m, color, icon, tp=None, **kwargs):
        """
        Create the control and apply the shape, if this is alrealdy stored
        in the guide controllers grp.

        Args:
            parent (dagNode): The control parent
            name (str): The control name.
            m (matrix): The transfromation matrix for the control.
            color (int or list of float): The color for the control in idex or RGB.
            icon (str): The controls default shape.
            tp (dagNode): Tag Parent Control object to connect as a parent controller
            kwargs (variant): Other arguments for the icon type variations.

        Returns:
            dagNode: The Control.

        """
        fullName = self.getName(name)
        bufferName = fullName + "_controlBuffer"
        if bufferName in self.rig.guide.controllers.keys():
            ctl_ref = self.rig.guide.controllers[bufferName]
            ctl = pri.addTransform(parent, fullName, m)
            for shape in ctl_ref.getShapes():
                ctl.addChild(shape, shape=True, add=True)
                pm.rename(shape, fullName + "Shape")
            ico.setcolor(ctl, color)
        else:
            ctl = ico.create(parent, fullName, m, color, icon, **kwargs)

        # create the attributes to handlde mirror and symetrical pose
        att.addAttribute(ctl,
                         "invTx",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror TX")
        att.addAttribute(ctl,
                         "invTy",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror TY")
        att.addAttribute(ctl,
                         "invTz",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror TZ")
        att.addAttribute(ctl,
                         "invRx",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror RX")
        att.addAttribute(ctl,
                         "invRy",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror RY")
        att.addAttribute(ctl,
                         "invRz",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror RZ")
        att.addAttribute(ctl,
                         "invSx",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror SX")
        att.addAttribute(ctl,
                         "invSy",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror SY")
        att.addAttribute(ctl,
                         "invSz",
                         "bool",
                         0,
                         keyable=False,
                         niceName="Invert Mirror SZ")

        if self.settings["ctlGrp"]:
            ctlGrp = self.settings["ctlGrp"]
            self.addToGroup(ctl, ctlGrp, "controllers")
        else:
            ctlGrp = "controllers"
            self.addToGroup(ctl, ctlGrp)

        #lock the control parent attributes if is not a control
        if parent not in self.groups[ctlGrp]:
            self.transform2Lock.append(parent)

        # Set the control shapes isHistoricallyInteresting
        for oShape in ctl.getShapes():
            oShape.isHistoricallyInteresting.set(False)

        #set controller tag
        if versions.current() >= 201650:
            try:
                oldTag = pm.PyNode(ctl.name() + "_tag")
                if not oldTag.controllerObject.connections():
                    # NOTE:  The next line is comment out. Because this will happend alot since maya does't clean
                    # controller tags after deleting the control Object of the tag. This have been log to Autodesk.
                    # If orphane tags are found, it will be clean in silence.
                    # pm.displayWarning("Orphane Tag: %s  will be delete and created new for: %s"%(oldTag.name(), ctl.name()))
                    pm.delete(oldTag)

            except:
                pass
            pm.controller(ctl)

            if tp:
                ctt = pm.PyNode(pm.controller(ctl, q=True)[0])
                tpTagNode = pm.PyNode(pm.controller(tp, q=True)[0])
                tpTagNode.cycleWalkSibling.set(True)
                pm.connectAttr(tpTagNode.prepopulate, ctt.prepopulate, f=True)
                # The connectAttr to the children attribute is giving error
                # i.e:  pm.connectAttr(ctt.attr("parent"), tpTagNode.attr("children"), na=True)
                # if using the next available option tag
                # I was expecting to use ctt.setParent(tp) but doest't work as expected.
                # After reading the documentation this method looks prety useless.
                # Looks like is boolean and works based on selection :(

                # this is a dirty loop workaround. Naaah!
                i = 0
                while True:
                    try:
                        pm.connectAttr(ctt.parent,
                                       tpTagNode.attr("children[%s]" % str(i)))
                        break
                    except:
                        i += 1
                        if i > 100:
                            pm.displayWarning(
                                "The controller tag for %s has reached the limit index of 100 children"
                                % ctl.name())
                            break

        return ctl
Exemplo n.º 15
0
def _createSoftTweakControls(name,
                             parent=None,
                             t=datatypes.Matrix(),
                             grps=None,
                             size=0.5):
    root_name = "{}_{}".format(name, "softTweak_root")
    namespace = None
    try:
        # simple check if exist a tweak with the same name
        exist = pm.PyNode(root_name)
        if exist:
            pm.displayError("the tweak: {} already exist. Please use a "
                            "unique name.".format(name))
            return False, False
    except pm.MayaNodeError:
        if parent:
            try:
                p = pm.PyNode(parent)
                namespace = p.namespace()

            except pm.MayaNodeError:
                pm.displayWarning("{} is not a valid parent or doesn't "
                                  "exist".format(parent))
                p = None
        else:
            p = None
        root = primitive.addTransform(p, root_name, t)
        attribute.addAttribute(root, "iconSize", "float", size, keyable=False)

        baseCtl = icon.create(parent=root,
                              name="{}_{}".format(name, "baseSoftTweak_ctl"),
                              m=t,
                              color=[1, 0.622, 0],
                              icon="square",
                              d=size,
                              w=size)
        tweakCtl = icon.create(parent=baseCtl,
                               name="{}_{}".format(name, "softTweak_ctl"),
                               m=t,
                               color=[0.89, 0.0, 0.143],
                               icon="diamond",
                               w=size * .8)
        attribute.addAttribute(tweakCtl, "falloff", "float", size)

        if grps:
            if not isinstance(grps, list):
                grps = [grps]
            for grp in grps:
                try:
                    # try if exist
                    oGrp = pm.PyNode(grp)
                except pm.MayaNodeError:
                    # create a new grp if does't exist
                    if len(grp.split("_")) >= 3:  # check  name convention
                        name = grp
                    else:
                        name = "rig_{}_grp".format(grp)

                        # namespace basic handling
                        # NOTE: Doesn't support more than one namespace stacked
                        if namespace and len(name.split(":")) < 2:
                            name = namespace + name

                    oGrp = pm.sets(n=name, em=True)

                pm.sets(oGrp, add=[baseCtl, tweakCtl])
        if t:
            root.setMatrix(t, worldSpace=True)

        return baseCtl, tweakCtl