예제 #1
0
    def attachSecondaryControlsToMainCurve(self):

        secControlsMerged = []
        tempMainCtlCurves = self.mainCtlCurves
        tempMainUpvCurves = self.mainCtlUpvs
        secControlsMerged.append(self.secondaryControls)

        for secCtl in self.secondaryControls:
            constraints.matrixConstraint(self.root, secCtl.getParent(2), 'rs',
                                         True)

            # controls tags
            # node.add_controller_tag(secCtl, tagParent=parent_tag_L)

        # create hooks on the main ctl curve
        for j, crv in enumerate(self.secondaryCurves):

            lvlType = 'transform'
            cvs = crv.getCVs(space="object")

            for i, cv in enumerate(cvs):

                oTransUpV = pm.PyNode(
                    pm.createNode(lvlType,
                                  n=self.getName("secNpoUpv",
                                                 str(i).zfill(3)),
                                  p=self.browsHooks_root,
                                  ss=True))
                oTrans = pm.PyNode(
                    pm.createNode(lvlType,
                                  n=self.getName("secNpo",
                                                 str(i).zfill(3)),
                                  p=self.browsHooks_root,
                                  ss=True))

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

                # create motion paths transforms on main ctl curves
                cns = applyPathCnsLocal(oTransUpV, tempMainUpvCurves[j], u)
                cns = applyPathCnsLocal(oTrans, tempMainCtlCurves[j], u)

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

                # connect secondary control to oTrans hook.
                constraints.matrixConstraint(
                    oTrans, secControlsMerged[j][i].getParent(2), 't', True)
예제 #2
0
def rig(edge_loop="",
        up_vertex="",
        low_vertex="",
        name_prefix="",
        thickness=0.3,
        do_skin=True,
        rigid_loops=5,
        falloff_loops=8,
        head_joint=None,
        jaw_joint=None,
        parent_node=None,
        control_name="ctl",
        upper_lip_ctl=None,
        lower_lip_ctl=None):

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

    FRONT_OFFSET = .02
    NB_ROPE = 15

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

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

    # Loop
    if edge_loop:
        try:
            edge_loop = [pm.PyNode(e) for e in edge_loop.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 up_vertex:
        try:
            up_vertex = pm.PyNode(up_vertex)
        except pm.MayaNodeError:
            pm.displayWarning("%s can not be found" % up_vertex)
            return
    else:
        pm.displayWarning("Please set the upper lip central vertex")
        return

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

    # skinnign data
    if do_skin:
        if not head_joint:
            pm.displayWarning("Please set the Head Jnt or unCheck Compute "
                              "Topological Autoskin")
            return
        else:
            try:
                head_joint = pm.PyNode(head_joint)
            except pm.MayaNodeError:
                pm.displayWarning(
                    "Head Joint: %s can not be found" % head_joint
                )
                return
        if not jaw_joint:
            pm.displayWarning("Please set the Jaw Jnt or unCheck Compute "
                              "Topological Autoskin")
            return
        else:
            try:
                jaw_joint = pm.PyNode(jaw_joint)
            except pm.MayaNodeError:
                pm.displayWarning("Jaw Joint: %s can not be found" % jaw_joint)
                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(edge_loop[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(edge_loop)
    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 = up_vertex
    lowPos = low_vertex

    # 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("upCtl_crv"),
                                           nbPoints=7,
                                           parent=lipsCrv_root)
    lowCrv_ctl = curve.createCurveFromCurve(lowCrv,
                                            setName("lowCtl_crv"),
                                            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)

    ##################
    # 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 head_joint and isinstance(head_joint, (str, string_types)):
            try:
                j_parent = pm.PyNode(head_joint)
            except pm.MayaNodeError:
                j_parent = False
        elif head_joint and isinstance(head_joint, pm.PyNode):
            j_parent = head_joint
        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 jaw_joint and isinstance(jaw_joint, (str, string_types)):
            try:
                j_parent = pm.PyNode(jaw_joint)
            except pm.MayaNodeError:
                pass
        elif jaw_joint and isinstance(jaw_joint, pm.PyNode):
            j_parent = jaw_joint
        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)

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

    # Controls lists
    upControls = []
    upVec = []
    upNpo = []
    lowControls = []
    lowVec = []
    lowNpo = []
    # controls options
    axis_list = ["sx", "sy", "sz", "ro"]
    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", "rx", "ry", "rz"]

    # 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

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

        # Get nearest joint for orientation of controls
        joints = upperJoints + lowerJoints
        nearest_joint = None
        nearest_distance = None
        for joint in joints:
            distance = vector.getDistance(
                transform.getTranslation(joint),
                cv
            )
            if nearest_distance is None or distance < nearest_distance:
                nearest_distance = distance
                nearest_joint = joint

        if nearest_joint:
            t = transform.setMatrixPosition(
                transform.getTransform(nearest_joint), cv
            )
            temp = primitive.addTransform(
                lips_root, setName("temp"), t
            )
            temp.rx.set(0)
            t = transform.getTransform(temp)
            pm.delete(temp)

        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, control_name), 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)
        name_split = control_name.split("_")
        if len(name_split) == 2 and name_split[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl)
        attribute.addAttribute(ctl, "isCtl", "bool", keyable=False)
        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)

        # Get nearest joint for orientation of controls
        joints = upperJoints + lowerJoints
        nearest_joint = None
        nearest_distance = None
        for joint in joints:
            distance = vector.getDistance(
                transform.getTranslation(joint),
                cv
            )
            if nearest_distance is None or distance < nearest_distance:
                nearest_distance = distance
                nearest_joint = joint

        if nearest_joint:
            t = transform.setMatrixPosition(
                transform.getTransform(nearest_joint), cv
            )
            temp = primitive.addTransform(
                lips_root, setName("temp"), t
            )
            temp.rx.set(0)
            t = transform.getTransform(temp)
            pm.delete(temp)

        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, control_name), 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)
        name_split = control_name.split("_")
        if len(name_split) == 2 and control_name.split("_")[-1] == "ghost":
            pass
        else:
            pm.sets(ctlSet, add=ctl)
        attribute.addAttribute(ctl, "isCtl", "bool", keyable=False)
        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, dropoffDistance=[0, 1000])
    pm.wire(lowCrv, w=lowCrv_ctl, dropoffDistance=[0, 1000])
    pm.wire(upRope, w=upCrv_ctl, dropoffDistance=[0, 1000])
    pm.wire(lowRope, w=lowCrv_ctl, dropoffDistance=[0, 1000])

    pm.wire(upRope_upv, w=upCrv_upv, dropoffDistance=[0, 1000])
    pm.wire(lowRope_upv, w=lowCrv_upv, dropoffDistance=[0, 1000])

    # 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.interpType.set(0)  # noFlip

    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.interpType.set(0)  # noFlip

    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.interpType.set(0)  # noFlip

    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)
    cns_node.interpType.set(0)  # noFlip

    # 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.interpType.set(0)  # noFlip

    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.interpType.set(0)  # noFlip

    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.interpType.set(0)  # noFlip

    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)
    cns_node.interpType.set(0)  # noFlip

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

        ref_ctls = [head_joint, jaw_joint]

        if upper_lip_ctl and lower_lip_ctl:
            try:
                if isinstance(upper_lip_ctl, string_types):
                    upper_lip_ctl = pm.PyNode(upper_lip_ctl)
            except pm.MayaNodeError:
                pm.displayWarning("Upper Lip Ctl %s. Can not be "
                                  "fount in the scene" % upper_lip_ctl)
                return
            try:
                if isinstance(lower_lip_ctl, string_types):
                    lower_lip_ctl = pm.PyNode(lower_lip_ctl)
            except pm.MayaNodeError:
                pm.displayWarning("Lower Lip Ctl %s. Can not be "
                                  "fount in the scene" % lower_lip_ctl)
                return
            ref_ctls = [upper_lip_ctl, lower_lip_ctl]

        # in order to avoid flips lets create a reference transform
        # also to avoid flips, set any multi target parentConstraint to noFlip
        ref_cns_list = []
        print (ref_ctls)
        for cns_ref in ref_ctls:

            t = transform.getTransformFromPos(
                cns_ref.getTranslation(space='world'))
            ref = pm.createNode("transform",
                                n=cns_ref.name() + "_cns",
                                p=cns_ref,
                                ss=True)
            ref.setMatrix(t, worldSpace=True)
            ref_cns_list.append(ref)
        # right corner connection
        cns_node = pm.parentConstraint(ref_cns_list[0],
                                       ref_cns_list[1],
                                       upControls[0].getParent(),
                                       mo=True)
        cns_node.interpType.set(0)  # noFlip
        # left corner connection
        cns_node = pm.parentConstraint(ref_cns_list[0],
                                       ref_cns_list[1],
                                       upControls[-1].getParent(),
                                       mo=True)
        cns_node.interpType.set(0)  # noFlip
        # up control connection
        cns_node = pm.parentConstraint(ref_cns_list[0],
                                       upControls[3].getParent(),
                                       mo=True)
        # low control connection
        cns_node = pm.parentConstraint(ref_cns_list[1],
                                       lowControls[2].getParent(),
                                       mo=True)

    ###########################################
    # Auto Skinning
    ###########################################
    if do_skin:
        # eyelid vertex rows
        totalLoops = rigid_loops + falloff_loops
        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(rigid_loops):
            for rr in range(2):
                skinPercList.append(1.0)
        increment = 1.0 / float(falloff_loops)
        # we invert to smooth out from 100 to 0
        inv = 1.0 - increment
        for r in range(falloff_loops):
            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 head_joint:
            try:
                head_joint = pm.PyNode(head_joint)
            except pm.MayaNodeError:
                pm.displayWarning(
                    "Auto skin aborted can not find %s " % head_joint)
                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(head_joint,
                                         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)