Animation and Rigging Tools: FAQ, Known Issues and Feature Roadmap

Many thanks! it worked!

Glad to help!

Finger FK/IK matching

Hi ,

Would it be possible for you check the following code for finger fk/ik matching?
And if it is good I would like to contribute it

in ART_animationUI.py:



    def match_finger_ik(self,character,finger,side,*args):

        fingerJoints = "01_", "02_", "03_"]
        fingerLocators = {}
        for index in fingerJoints:
            fingerLocators[index] = cmds.spaceLocator()[0]
        for index in fingerJoints:
            cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + index + side, fingerLocators[index])[0])
        
        constraints = {}
        for index in fingerJoints:
            constraints  index ] = cmds.orientConstraint( fingerLocators[index ], character + ":" + finger + "finger_fk_ctrl_" + index[1:] +  side )[0]

        for index in fingerJoints:
            cmds.setKeyframe(character + ":" + finger + "finger_fk_ctrl_" + index[1:] +  side )

 
        for index in fingerJoints:
            cmds.delete(constraints[index])

        for index in fingerJoints:
            cmds.delete(fingerLocators[index])
 
    def getScaleFactor(self,character):
        
        return cmds.getAttr(character + ":" + "Rig_Settings.scaleFactor")
    
   

    def match_finger_fk(self,character, finger,side,scaleFactor ,*args):

            finger01Loc = cmds.spaceLocator()[0]
            finger02Loc = cmds.spaceLocator()[0]
            finger03Loc = cmds.spaceLocator()[0]

            #constrain to the arm driver joints

            cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + "01_" + side, finger01Loc )[0])
            cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + "02_" + side, finger02Loc )[0])
            cmds.delete(cmds.parentConstraint(character + ":driver_"+ finger + "03_" + side, finger03Loc )[0])



            #create a fourth locator for the wrist, parent under the handLoc and rotate 90 in X
            fingerOffset = cmds.duplicate(finger03Loc)[0]
            cmds.parent(fingerOffset, finger03Loc)
            if side == "l":
                cmds.setAttr(fingerOffset + ".tx",5*scaleFactor)
            else:
                cmds.setAttr(fingerOffset + ".tx",-5*scaleFactor)
            #if side == "l":
            #    cmds.setAttr(fingerOffset + ".rotateX", 90)
            #else:
            #    cmds.setAttr(fingerOffset + ".rotateX", -90)

            #constrain the elbow control to the elbow locator
            # if cmds.objExists(character + ":elbowswitch_"+side):
            #     ptCnst = cmds.pointConstraint(character + ":elbowswitch_"+side, character + ":ik_elbow_" + side + "_anim")
            #
            # else:

            pntConst = cmds.pointConstraint(finger02Loc , character + ":"+ finger+side + "_poleVector")[0]

            #constrain the wrist
            constraint = cmds.parentConstraint(fingerOffset , character + ":"+ finger + side + "_ik_anim")[0]

            #set keys
            cmds.setKeyframe(character + ":"+ finger+side + "_poleVector")
            cmds.setKeyframe(character + ":"+ finger+ side + "_ik_anim")

    # if cmds.objExists(character + ":elbowswitch_"+side):
    #     cmds.delete(ptCnst)

            cmds.delete(constraint)
            cmds.delete(pntConst)
            cmds.delete(finger01Loc)
            cmds.delete(finger02Loc)
            cmds.delete(finger03Loc)


    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
    def match_singleFrame(self, limb, side, matchFrom, matchTo, solveRoll = False, *args):

        autoKeyOn = False
        if cmds.autoKeyframe(q = True, state = True):
            cmds.autoKeyframe(state = False)
            autoKeyOn = True

        #get the passed in limb, and duplicate the skeleton for that limb's current mode
        #for example, if limb is left arm, and matchFrom is IK, then dupe the driver joints (in IK pose) for the left arm and parent to world
        character = cmds.symbolButton(self.widgets"activeCharacterThumb"], q = True, ann = True)

        armBones = "upperarm_", "lowerarm_", "hand_"]
        spineBones = "driver_spine_01", "driver_spine_02", "driver_spine_03", "driver_spine_04", "driver_spine_05"]
        legBones = "thigh_", "calf_", "foot_", "ball_"]
        
        fingerBones = "thumb", "index", "middle", "ring", "pinky"]
        fingerJoints = "01_", "02_", "03_"]        

        #grab current selection
        currentSelection = cmds.ls(sl = True)

        if limb == "fingers":
        
            
            if matchTo == "IK":
                for fingerBone in fingerBones:
                    self.match_finger_ik(character,fingerBone+"_",side)

            if matchTo == "FK":
                
                scaleFactor =  self.getScaleFactor(character)
                
                for fingerBone in fingerBones:
                    self.match_finger_fk(character,fingerBone+"_",side,scaleFactor)
        
        if limb in fingerBones:
            if matchTo == "IK":
                self.match_finger_ik(character, limb+"_",side)
            if matchTo == "FK":
                scaleFactor =  self.getScaleFactor(character)
                self.match_finger_fk(character,limb+"_",side,scaleFactor)
                
                

        #arm matching
        if limb == "arm":
            #setup constraints based on mode info
            if matchTo == "IK":

                #create 3 locators in world space
                upArmLoc = cmds.spaceLocator()[0]
                lowArmLoc = cmds.spaceLocator()[0]
                handLoc = cmds.spaceLocator()[0]

                #constrain to the arm driver joints
                cmds.delete(cmds.parentConstraint(character + ":driver_upperarm_" + side, upArmLoc)[0])
                cmds.delete(cmds.parentConstraint(character + ":driver_lowerarm_" + side, lowArmLoc)[0])
                cmds.delete(cmds.parentConstraint(character + ":driver_hand_" + side, handLoc)[0])

                #constrain FK controls to the locators
                constraint1 = cmds.orientConstraint(upArmLoc, character + ":fk_arm_" + side + "_anim")[0]
                constraint2 = cmds.orientConstraint(lowArmLoc, character + ":fk_elbow_" + side + "_anim")[0]
                constraint3 = cmds.orientConstraint(handLoc, character + ":fk_wrist_" + side + "_anim")[0]

                # constraint1 = cmds.orientConstraint(character + ":ik_upperarm_fk_matcher_" + side, character + ":fk_arm_" + side + "_anim")[0]
                # constraint2 = cmds.orientConstraint(character + ":ik_lowerarm_fk_matcher_" + side, character + ":fk_elbow_" + side + "_anim")[0]
                # constraint3 = cmds.orientConstraint(character + ":hand_match_loc_" + side, character + ":fk_wrist_" + side + "_anim")[0]

                cmds.setKeyframe(character + ":fk_arm_" + side + "_anim")
                cmds.setKeyframe(character + ":fk_elbow_" + side + "_anim")
                cmds.setKeyframe(character + ":fk_wrist_" + side + "_anim")

                cmds.delete(constraint1)
                cmds.delete(constraint2)
                cmds.delete(constraint3)

                cmds.delete(upArmLoc)
                cmds.delete(lowArmLoc)
                cmds.delete(handLoc)



            if matchTo == "FK":


                #create 3 locators in world space
                upArmLoc = cmds.spaceLocator()[0]
                lowArmLoc = cmds.spaceLocator()[0]
                handLoc = cmds.spaceLocator()[0]

                #constrain to the arm driver joints
                cmds.delete(cmds.parentConstraint(character + ":driver_upperarm_" + side, upArmLoc)[0])
                cmds.delete(cmds.parentConstraint(character + ":driver_lowerarm_" + side, lowArmLoc)[0])
                cmds.delete(cmds.parentConstraint(character + ":driver_hand_" + side, handLoc)[0])

                #create a fourth locator for the wrist, parent under the handLoc and rotate 90 in X
                handOffset = cmds.duplicate(handLoc)[0]
                cmds.parent(handOffset, handLoc)
                if side == "l":
                    cmds.setAttr(handOffset + ".rotateX", 90)
                else:
                    cmds.setAttr(handOffset + ".rotateX", -90)

                #constrain the elbow control to the elbow locator
                # if cmds.objExists(character + ":elbowswitch_"+side):
                #     ptCnst = cmds.pointConstraint(character + ":elbowswitch_"+side, character + ":ik_elbow_" + side + "_anim")
                #
                # else:
                pntConst = cmds.pointConstraint(lowArmLoc, character + ":ik_elbow_" + side + "_anim")[0]

                #constrain the wrist
                constraint = cmds.parentConstraint(handOffset, character + ":ik_wrist_" + side + "_anim")[0]

                #set keys
                cmds.setKeyframe(character + ":ik_wrist_" + side + "_anim")
                cmds.setKeyframe(character + ":ik_elbow_" + side + "_anim")

                # if cmds.objExists(character + ":elbowswitch_"+side):
                #     cmds.delete(ptCnst)

                cmds.delete(constraint)
                cmds.delete(pntConst)
                cmds.delete(upArmLoc)
                cmds.delete(lowArmLoc)
                cmds.delete(handLoc)



                # dupeNodes = cmds.duplicate(character + ":driver_" + armBones[0] + side)
                #
                # parent = cmds.listRelatives(dupeNodes[0], parent = True)
                # if parent != None:
                #     cmds.parent(dupeNodes[0], world = True)
                #
                # cmds.pointConstraint("driver_hand_" + side, character + ":ik_wrist_" + side + "_anim")
                # constraint = cmds.orientConstraint(character + ":fk_wrist_" + side + "_anim", character + ":ik_wrist_" + side + "_anim")[0]
                #
                # # CRA NEW CODE - For making sure the elbow match doesnt cause any weird twisting issues.
                # if cmds.objExists(character + ":elbowswitch_"+side):
                #     print "NEW CODE WORKING"
                #     ptCnst = cmds.pointConstraint(character + ":elbowswitch_"+side, character + ":ik_elbow_" + side + "_anim")
                # else:
                #     cmds.pointConstraint("driver_lowerarm_"+side, character + ":ik_elbow_" + side + "_anim")
                # # CRA END NEW CODE
                #
                # if side == "l":
                #     cmds.setAttr(constraint + ".offsetX", 90)
                #
                # if side == "r":
                #     cmds.setAttr(constraint + ".offsetX", -90)
                #
                #
                # cmds.setKeyframe(character + ":ik_wrist_" + side + "_anim")
                # cmds.setKeyframe(character + ":ik_elbow_" + side + "_anim")
                #
                # # CRA NEW CODE
                # if cmds.objExists(character + ":elbowswitch_"+side):
                #     cmds.delete(ptCnst)
                # # CRA END NEW CODE
                #
                # cmds.delete(constraint)
                # #delete the original mode pose joints
                # cmds.delete(dupeNodes[0])


        if limb == "clav":
            #setup constraints based on mode info
            if matchTo == "IK":

                constraint1 = cmds.orientConstraint(character + ":ik_clavicle_" + side, character + ":fk_clavicle_" + side + "_anim")[0]
                cmds.setKeyframe(character + ":fk_clavicle_" + side + "_anim")
                cmds.delete(constraint1)

            if matchTo == "FK":

                constraint1 = cmds.pointConstraint(character + ":driver_upperarm_" + side, character + ":clavicle_" + side + "_anim")[0]
                cmds.setKeyframe(character + ":clavicle_" + side + "_anim")
                cmds.delete(constraint1)






        #leg matching
        attrList = cmds.listAttr(character + ":Skeleton_Settings", shortNames=True)
        for i in attrList:
            if i == "legStyle":
                legStyle = cmds.getAttr(character+":Skeleton_Settings.legStyle")

        if limb == "leg":
            dupeNodes = cmds.duplicate(character + ":" + legBones[0] + side)

            parent = cmds.listRelatives(dupeNodes[0], parent = True)
            if parent != None:
                cmds.parent(dupeNodes[0], world = True)


            #setup constraints based on mode info
            if matchTo == "IK":

                cmds.orientConstraint("thigh_" + side, character + ":fk_thigh_" + side + "_anim")
                cmds.orientConstraint("calf_" + side, character + ":fk_calf_" + side + "_anim")
                if legStyle == 1:
                    cmds.orientConstraint("heel_" + side, character + ":fk_heel_" + side + "_anim")
                cmds.orientConstraint("foot_" + side, character + ":fk_foot_" + side + "_anim")

                if cmds.objExists("ball_" + side):
                    cmds.orientConstraint("ball_" + side, character + ":fk_ball_" + side + "_anim")


                cmds.setKeyframe(character + ":fk_thigh_" + side + "_anim")
                cmds.setKeyframe(character + ":fk_calf_" + side + "_anim")
                if legStyle == 1:
                    cmds.setKeyframe(character + ":fk_heel_" + side + "_anim")
                cmds.setKeyframe(character + ":fk_foot_" + side + "_anim")
                if cmds.objExists("ball_" + side):
                    cmds.setKeyframe(character + ":fk_ball_" + side + "_anim")



            if matchTo == "FK":

                cmds.select(clear = True)
                loc1 = character + ":matchLoc_knee_1_" + side
                loc2 = character + ":matchLoc_knee_2_" + side

                #setup constraints
                for ctrl in ":heel_ctrl_" + side, ":toe_wiggle_ctrl_" + side, ":toe_tip_ctrl_" + side, ":ik_foot_anim_" + side]:
                    cmds.select(character + ctrl, add = True)

                self.resetSelection()
                cmds.setKeyframe()

                #reverse foot matching setup
                if solveRoll:
                    if cmds.objExists(character + ":fk_ball_" + side + "_anim"):
                        cmds.refresh(force = True)
                        footLoc = cmds.spaceLocator(name = character + ":matchLoc_foot_" + side)[0]
                        ikFootLoc = cmds.spaceLocator(name = character + ":matchLoc_ik_foot_" + side)[0]
                        toeLoc = cmds.spaceLocator(name = character + ":matchLoc_toe_" + side)[0]

                        cmds.parent(footLoc, character + ":fk_ball_" + side + "_anim")
                        cmds.parent(toeLoc, character + ":fk_foot_" + side + "_anim")

                        cmds.parentConstraint(character + ":fk_foot_" + side + "_anim", footLoc)
                        cmds.parentConstraint(character + ":fk_ball_" + side + "_anim", toeLoc)
                        const = cmds.parentConstraint(character + ":master_foot_ball_pivot_" + side, ikFootLoc)[0]
                        cmds.delete(const)


                        #world position locators
                        startPos = cmds.spaceLocator()[0]
                        midPos = cmds.spaceLocator()[0]
                        endPos = cmds.spaceLocator()[0]

                        cmds.parentConstraint(footLoc, startPos)
                        cmds.parentConstraint(toeLoc, midPos)
                        cmds.parentConstraint(character + ":foot_ikHandle_" + side, endPos)

                    else:
                        solveRoll = False



                if not solveRoll:
                    loc = cmds.spaceLocator(name = character + ":ik_foot_anim_" + side + "_locator")[0]
                    constraint = cmds.parentConstraint("foot_" + side, loc)[0]
                    cmds.delete(constraint)

                    cmds.pointConstraint(loc, character + ":ik_foot_anim_" + side)
                    constraint = cmds.orientConstraint(loc, character + ":ik_foot_anim_" + side)[0]

                    if side == "l":
                        cmds.setAttr(constraint + ".offsetY", 90)

                    if side == "r":
                        cmds.setAttr(constraint + ".offsetX", 180)
                        cmds.setAttr(constraint + ".offsetY", 90)

                else:
                    ikFootConst = cmds.parentConstraint(ikFootLoc, character + ":ik_foot_anim_" + side, mo = True)[0]
                    cmds.parentConstraint(toeLoc, ikFootLoc)

                    cmds.setAttr(character + ":Rig_Settings." + side + "LegMode", 1)
                    cmds.setKeyframe(character + ":Rig_Settings." + side + "LegMode")

                    #heel solve
                    self.ikHeelSolve(character, side, startPos, midPos, endPos)

                    cmds.setAttr(character + ":Rig_Settings." + side + "LegMode", 0)
                    cmds.setKeyframe(character + ":Rig_Settings." + side + "LegMode")


                cmds.setKeyframe(character + ":ik_foot_anim_" + side)



                #knee solve
                for x in range(1500):
                    angle = self.getAngleBetween(loc1, loc2)
                    if abs(angle) > .25:
                        self.ikKneeSolve(character, side, angle, loc1, loc2)
                    else:
                        break
                if not solveRoll:
                    cmds.delete(loc)

                else:
                    cmds.delete(footLoc)
                    cmds.delete(ikFootLoc)
                    cmds.delete(toeLoc)

                cmds.setKeyframe(character + ":ik_foot_anim_" + side)

            #delete the original mode pose joints
            cmds.delete(dupeNodes[0])


        #spine matching
        if limb == "spine":
            dupeNodes = cmds.duplicate(character + ":" + spineBones[0])

            parent = cmds.listRelatives(dupeNodes[0], parent = True)
            if parent != None:
                cmds.parent(dupeNodes[0], world = True)

            #setup constraints based on mode info
            # Switching to FK
            if matchTo == "IK":

                #check to see if user has any project specific match scripts (Fortnite custom)
                if cmds.objExists(character + ":spine_02_anim.driven"):
                    #furthermore, if the plusMinusAvg nodes exist, then import custom matching
                    if os.path.exists(self.mayaToolsDir + "/General/Scripts/fortniteRotoMatch.py"):

                        result = cmds.confirmDialog(title = "Match Options", icon = "question", message = "Which match option would you like to use?", button = "Standard", "Rotoscope"])

                        if result == "Standard":

                            try:
                                cmds.setAttr(character + ":spine_02_anim.driven", 0)
                                cmds.setAttr(character + ":spine_04_anim.driven", 0)
                            except:
                                pass

                            if cmds.objExists(character + ":spine_01_anim"):
                                cmds.orientConstraint("driver_spine_01", character + ":spine_01_anim")
                                cmds.setKeyframe(character + ":spine_01_anim")

                            if cmds.objExists(character + ":spine_02_anim"):
                                cmds.orientConstraint("driver_spine_02", character + ":spine_02_anim")
                                cmds.setKeyframe(character + ":spine_02_anim")

                            if cmds.objExists(character + ":spine_03_anim"):
                                cmds.orientConstraint("driver_spine_03", character + ":spine_03_anim")
                                cmds.setKeyframe(character + ":spine_03_anim")

                            if cmds.objExists(character + ":spine_04_anim"):
                                cmds.orientConstraint("driver_spine_04", character + ":spine_04_anim")
                                cmds.setKeyframe(character + ":spine_04_anim")

                            if cmds.objExists(character + ":spine_05_anim"):
                                cmds.orientConstraint("driver_spine_05", character + ":spine_05_anim")
                                cmds.setKeyframe(character + ":spine_05_anim")

                            #for each in spineBones:
                                #if cmds.objExists(character + ":" + each + "_anim"):
                                    #cmds.setKeyframe(character + ":" + each + "_anim")


                        if result == "Rotoscope":
                            import fortniteRotoMatch as fnRm
                            reload(fnRm)
                            fnRm.RotoSpineMatch(character)


                else:
                    if cmds.objExists(character + ":spine_01_anim"):
                        cmds.orientConstraint("driver_spine_01", character + ":spine_01_anim")
                        cmds.setKeyframe(character + ":spine_01_anim")

                    if cmds.objExists(character + ":spine_02_anim"):
                        cmds.orientConstraint("driver_spine_02", character + ":spine_02_anim")
                        cmds.setKeyframe(character + ":spine_02_anim")

                    if cmds.objExists(character + ":spine_03_anim"):
                        cmds.orientConstraint("driver_spine_03", character + ":spine_03_anim")
                        cmds.setKeyframe(character + ":spine_03_anim")

                    if cmds.objExists(character + ":spine_04_anim"):
                        cmds.orientConstraint("driver_spine_04", character + ":spine_04_anim")
                        cmds.setKeyframe(character + ":spine_04_anim")

                    if cmds.objExists(character + ":spine_05_anim"):
                        cmds.orientConstraint("driver_spine_05", character + ":spine_05_anim")
                        cmds.setKeyframe(character + ":spine_05_anim")

                    #for each in spineBones:
                        #if cmds.objExists(character + ":" + each + "_anim"):
                            #cmds.setKeyframe(character + ":" + each + "_anim")

            # Switching to IK
            if matchTo == "FK":

                if cmds.objExists(character + ":chest_ik_anim"):

                    #find highest spine joint
                    numSpineBones = cmds.getAttr(character + ":Skeleton_Settings.numSpineBones")
                    if numSpineBones == 5:
                        endSpine = "driver_spine_05"
                        midSpine = "driver_spine_03"]

                    if numSpineBones == 4:
                        endSpine = "driver_spine_04"
                        midSpine = "driver_spine_02", "driver_spine_03"]

                    if numSpineBones == 3:
                        endSpine = "driver_spine_03"
                        midSpine = "driver_spine_02"]

                    if cmds.objExists("chest_ik_anim_MATCH"):
                        cmds.parentConstraint("chest_ik_anim_MATCH", character + ":chest_ik_anim")
                        cmds.parentConstraint("mid_ik_anim_MATCH", character + ":mid_ik_anim")
                    else:
                        cmds.parentConstraint(endSpine, character + ":chest_ik_anim")
                        for each in midSpine:
                            cmds.parentConstraint(each, character + ":mid_ik_anim")

                cmds.setKeyframe([character + ":chest_ik_anim", character + ":mid_ik_anim"])


            #delete the original mode pose joints
            cmds.delete(dupeNodes[0])


        #reselect selection before entering process
        if len(currentSelection) > 0:
            cmds.select(currentSelection)


        if autoKeyOn:
            cmds.autoKeyframe(state = True)




in ART_autorigger.py:



class AutoRigger():

    def __init__(self, handCtrlSpace, progressBar):


        self.handCtrlSpace = handCtrlSpace

        #get access to our maya tools
        toolsPath = cmds.internalVar(usd = True) + "mayaTools.txt"
        if os.path.exists(toolsPath):

            f = open(toolsPath, 'r')
            self.mayaToolsDir = f.readline()
            f.close()


        #create a progress window to track the progress of the rig build
        self.progress = 0
        cmds.progressBar(progressBar, edit = True, progress=self.progress, status='Creating Spine Rig')



        #build the core of the rig
        import Modules.ART_Core
        coreNodes = Modules.ART_Core.RigCore()
        
        cmds.select("Rig_Settings",r=True)
        cmds.addAttr(ln="scaleFactor",at="float", keyable = False)
        cmds.setAttr("Rig_Settings."+"scaleFactor",utils.getScaleFactor(),lock=True)
        cmds.select(cl=True)
        #BODY CONTROL
        self.buildHips()

        """
        #create the rig settings node
        "Rig_Settings" = cmds.group(empty = True, name = "Rig_Settings")
        cmds.setAttr("Rig_Settings" + ".tx", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".ty", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".tz", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".rx", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".ry", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".rz", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".sx", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".sy", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".sz", lock = True, keyable = False)
        cmds.setAttr("Rig_Settings" + ".v", lock = True, keyable = False)


        #build the spine rigs
        self.createDriverSkeleton()
        self.buildCoreComponents()
        """

        #to be replaced by modules
        fkControls = self.buildFKSpine()
        ikControls = self.buildIKSpine(fkControls)


        #build the leg rigs

        #first determine the leg style
        legStyle = cmds.getAttr("SkeletonSettings_Cache.legStyle")

        if legStyle == "Standard Biped":
            cmds.progressBar(progressBar, edit = True, progress = 20, status='Creating Leg Rigs')
            self.buildFKLegs()
            self.buildIKLegs()
            self.finishLegs()


            cmds.progressBar(progressBar, edit = True, progress = 30, status='Creating Toe Rigs')
            self.buildToes()
            cmds.progressBar(progressBar, edit = True, progress = 40, status='Creating Auto Hips and Spine')
            self.buildAutoHips()
            self.autoSpine()

        if legStyle == "Hind Leg":
            cmds.progressBar(progressBar, edit = True, progress = 20, status='Creating Leg Rigs')
            self.buildFKLegs_hind()
            self.buildIKLegs_hind()
            self.finishLegs_hind()


            cmds.progressBar(progressBar, edit = True, progress = 30, status='Creating Toe Rigs')
            self.buildToes()
            cmds.progressBar(progressBar, edit = True, progress = 40, status='Creating Auto Hips and Spine')
            self.buildAutoHips()
            self.autoSpine()



        #build the arms
        cmds.progressBar(progressBar, edit = True, progress = 50, status='Creating Arm Rigs')
        spineBones = self.getSpineJoints()
        lastSpine = "driver_" + spineBones-1]
        print lastSpine
        import Modules.ART_Arm
        reload(Modules.ART_Arm)
        Modules.ART_Arm.Arm(True, "", None, "l", lastSpine, 6, True)
        Modules.ART_Arm.Arm(True, "", None, "r", lastSpine, 13, True)


        """
        self.buildFKArms()
        self.buildIkArms()
        """

        cmds.progressBar(progressBar, edit = True, progress = 60, status='Creating Finger Rigs')
        self.buildFingers()

        #build the neck and head rig
        cmds.progressBar(progressBar, edit = True, progress = 70, status='Creating Neck and Head Rigs')
        self.buildNeckAndHead()


        #rig extra joints
        cmds.progressBar(progressBar, edit = True, progress = 80, status='Creating Rigs for Custom Joints')
        createdControls = self.rigLeafJoints()
        createdJiggleNodes = self.rigJiggleJoints()
        createdChainNodes = self.rigCustomJointChains()





        #clean up the hierarchy
        cmds.progressBar(progressBar, edit = True, progress = 90, status='Cleaning up Scene')

        bodyGrp = cmds.group(empty = True, name = "body_grp")
        for obj in "spine_splineIK_curve", "splineIK_spine_01_splineIK", "body_anim_space_switcher_follow"]:
            if cmds.objExists(obj):
                cmds.parent(obj, bodyGrp)

        if cmds.objExists("autoHips_sys_grp"):
            cmds.parent("autoHips_sys_grp", "body_anim")


        rigGrp = "ctrl_rig"
        cmds.parent([bodyGrp, "leg_sys_grp"], rigGrp)

        """
        rigGrp = cmds.group(empty = True, name = "ctrl_rig")
        cmds.parent([bodyGrp, "leg_sys_grp", "Rig_Settings"], rigGrp)
	cmds.parent(rigGrp, "offset_anim")
	"""


        #Arms
        """
        if cmds.objExists("arm_rig_master_grp_l"):
            cmds.setAttr("Rig_Settings.lArmMode", 1)

	    if cmds.objExists("lowerarm_l_roll_grp"):
		cmds.parent("lowerarm_l_roll_grp", "arm_rig_master_grp_l")

            cmds.parent("arm_rig_master_grp_l", "ctrl_rig")


        if cmds.objExists("arm_rig_master_grp_r"):
            cmds.setAttr("Rig_Settings.rArmMode", 1)

	    if cmds.objExists("lowerarm_r_roll_grp"):
		cmds.parent("lowerarm_r_roll_grp", "arm_rig_master_grp_r")

            cmds.parent("arm_rig_master_grp_r", "ctrl_rig")

        if cmds.objExists("arm_rig_master_grp_r") and cmds.objExists("arm_rig_master_grp_l"):
            armSysGrp = cmds.group(empty = True, name = "arm_sys_grp")
            cmds.parent(armSysGrp, "ctrl_rig")
            cmds.parent("arm_rig_master_grp_r", "arm_rig_master_grp_l", "ik_wrist_l_anim_space_switcher_follow", "ik_wrist_r_anim_space_switcher_follow"], armSysGrp)

	    #arm twists
	    if cmds.objExists("upperarm_twist_grp_l"):
		cmds.parent("upperarm_twist_grp_l", armSysGrp)

	    if cmds.objExists("upperarm_twist_grp_r"):
		cmds.parent("upperarm_twist_grp_r", armSysGrp)
	"""


        if cmds.objExists("neck_01_fk_anim_grp"):
            cmds.parent("neck_01_fk_anim_grp", "ctrl_rig")

        #Fingers
        if cmds.objExists("finger_sys_grp_l"):
            cmds.parent("finger_sys_grp_l", "ctrl_rig")

        if cmds.objExists("finger_sys_grp_r"):
            cmds.parent("finger_sys_grp_r", "ctrl_rig")


        #Custom Joints (leaf, jiggle, chain)
        if len(createdControls) > 0:
            for each in createdControls:
                cmds.parent(each, "ctrl_rig")

        if len(createdJiggleNodes) > 0:
            for each in createdJiggleNodes:
                cmds.parent(each, "ctrl_rig")

        if len(createdChainNodes) > 0:
            for each in createdChainNodes:
                cmds.parent(each, "ctrl_rig")

        cmds.parent("head_sys_grp", "ctrl_rig")

        #finish grouping everything under 1 character grp
        if cmds.objExists("Proxy_Geo_Skin_Grp"):
            try:
                cmds.parent("Proxy_Geo_Skin_Grp", "rig_grp")
            except:
                pass

        if cmds.objExists("dynHairChain"):
            try:
                cmds.parent("dynHairChain", "rig_grp")
            except:
                pass


        #add world spaces to each space switch control
        self.addSpaces()

        #Hide all joints
        joints = cmds.ls(type = 'joint')
        for joint in joints:
            if cmds.getAttr(joint + ".v", settable = True):
                cmds.setAttr(joint + ".v", 0)
        cmds.progressBar(progressBar, edit = True, progress = 100, status='Cleaning up Scene')

        #delete the joint mover
        cmds.select("root_mover_grp", r = True, hi = True)
        cmds.select("Skeleton_Settings", add = True)
        nodes = cmds.ls(sl = True, transforms = True)
        cmds.select(clear = True)

        for node in nodes:
            cmds.lockNode(node, lock = False)
        cmds.lockNode("JointMover", lock = False)
        cmds.delete("JointMover")

        #find and delete junk nodes/clean scene
        for obj in "invis_legs_Rig_Settings", "invis_legs_Rig_Settings1", "invis_legs_spine_splineIK_curve", "invis_legs_spine_splineIK_curve1","invis_legs_master_anim_space_switcher_follow", "invis_legs_master_anim_space_switcher_follow1"]:
            try:
                cmds.select("*" + obj + "*")
                selection = cmds.ls(sl = True)
                for each in selection:
                    if cmds.objExists(each):
                        cmds.delete(each)
            except:
                pass


        cmds.select(all = True)
        selection = cmds.ls(sl = True)

        for each in selection:
            if each.find("invis_") == 0:

                try:
                    parent = cmds.listRelatives(each, parent = True)
                    if parent == None:
                        cmds.delete(each)
                except:
                    pass

        #New IK KNEE MATCHING STUFF!
        loc1 = cmds.spaceLocator(name = "matchLoc_knee_1_l")
        loc2 = cmds.spaceLocator(name = "matchLoc_knee_2_l")

        constraint = cmds.pointConstraint("fk_calf_l_anim", loc1)[0]
        cmds.delete(constraint)
        cmds.parent(loc1, "fk_calf_l_anim")

        constraint = cmds.pointConstraint("ik_leg_calf_l", loc2)[0]
        cmds.delete(constraint)
        cmds.parent(loc2, "ik_leg_calf_l")

        cmds.select(loc1)
        cmds.move(0, -30, 0, r = True)

        cmds.select(loc2)
        cmds.move(0, -30, 0, r = True)
        cmds.setAttr(loc1[0] + ".v", 0)
        cmds.setAttr(loc2[0] + ".v", 0)




        loc1 = cmds.spaceLocator(name = "matchLoc_knee_1_r")
        loc2 = cmds.spaceLocator(name = "matchLoc_knee_2_r")

        constraint = cmds.pointConstraint("fk_calf_r_anim", loc1)[0]
        cmds.delete(constraint)
        cmds.parent(loc1, "fk_calf_r_anim")

        constraint = cmds.pointConstraint("ik_leg_calf_r", loc2)[0]
        cmds.delete(constraint)
        cmds.parent(loc2, "ik_leg_calf_r")

        cmds.select(loc1)
        cmds.move(0, -30, 0, r = True)

        cmds.select(loc2)
        cmds.move(0, -30, 0, r = True)
        cmds.setAttr(loc1[0] + ".v", 0)
        cmds.setAttr(loc2[0] + ".v", 0)




        #set default rotate Orders
        self.setDefaultRotateOrders()

        #end progress window
        cmds.select(clear = True)



Motion Import bug

There is a bug in the motion import class that causes the an incorrect project path to be stored if there is a reference with “Project” in it’s path but not in the ART project path.
This causes the import motion class not being able to read the saved animation.

Solution:




class ImportMotionUI():

    def __init__(self, uiInst):

        #create class variables
        self.widgets = {}
        self.selection = cmds.ls(sl = True)
        self.uiInst = uiInst

        #get access to our maya tools
        toolsPath = cmds.internalVar(usd = True) + "mayaTools.txt"
        if os.path.exists(toolsPath):

            f = open(toolsPath, 'r')
            self.mayaToolsDir = f.readline()
            f.close()
            
            
        #find out which project we are in
        references = cmds.ls(type = "reference")
        for ref in references:
            try:
                query = cmds.referenceQuery(ref, filename = True)
                #check if the reference is in the ART project path
                if query.find(self.mayaToolsDir) != -1:  
                    self.project = query.rpartition("Projects/")[2].partition("/")[0]

            except:
                pass


I’m using A.R.T.1.0 in Maya 2016. After turning off the AIM, twists the arms and legs do not move to the correct position. rotation correct

@lion032 OR ANYONE D: Please help, im trying to edit an existing animation. When i click thru the frames and for example turning the character upside down and then change frame, go back to edited frame.Then the frame stays the same as before i edited it. How do i save án edited frame in an animation?

Add the controllers you want to edit to an animation layer edit them there and key that.

Thank you, got it working! :slight_smile: I have 1 more question. How do i mirror left hand to right hand inside an animation frame. And after that how can i copy the frame to next frame so i can continue animating from there?

To mirror animation you’ll need to get the Maya bonus tools form here:

https://apps.autodesk.com/en/Detail/Index?id=8115150172702393827&appLang=en&os=Win64&autostart=true

And here is how to use them:

Thank you so much!

Can i ask you one more thing? I have imported an idle animation. I want the hands to be raised in a certain way every frame. I dont want to change anything else. Is there a way to copy the arms only from frame to frame?

To be honest I started animating only about a month ago so the next approach might be the not best one but this is how I would have approached it.

  1. Using the pose editor of ART save the pose you want for the body.
  2. Add all of the controllers you want to remain the same to an override animation layer.
  3. On frame 0 of the override layer right click the layer and select layer objects.
  4. With override layer objects selected right click the saved pose and click on “Load World space on selected controllers”

Anyone else having a hell of a time exporting looping animations with jiggle joints? Even though the loop is perfect and smooth in Maya, when I export it into the engine the jiggle bones snap pretty hard.

I’m going to ask an incredibly stupid question and I hope someone can answer it for me. Given a FBX - a model that was made in a different program (Cinema4d) - is there any good way to get it into ART? We have the C4D files for it, can export it any way C4D will export.

Getting the file into ART shouldn’t be the issue since it allready is .fbx, but you will need to redo all the advanced setups like IK/FK, Constraints, Helpers etc. even on a reimport to Cinema, because these things don’t transfer over to fbx.

So if you have a animatable rig in .c4d format, you either animate it there and export the results or you just export the model and skeleton and set up the rig in the app you’re going to animate it in.

The reason is simple: while every program uses much similar principles of animation, each one has it’s own setup for these funktions and they cannot be converted.

For Example: if you use Coffee scripts in Cinema 4D to make a chain of bones behave a certain way when rotating a helper object (FK), Maya might have a much similar setup, but wouldn’t understand the Coffee script even if it was possible to export it.

I guess it’s not even possible to transfer rigs between Max and Maya, allthough they are both owned by the same company.

Thaaat’s what I was afraid of. I was given a 2017 .mb, and all I have is 2014. Can’t roll it back nohow!

I have rigged my fbx character using the Maya A.R.T, and I built a .mb file. This is my mesh with a skeleton, correct? How do I import this into UE (as it’s not a .fbx file but a .mb file)?

Hey Mykita,

To get it into engine, you need to open the export file in Maya, select your geometry, select your joints, then export as an FBX. With that FBX you should be able to import into the engine.

Hi guys,

I’m using A.R.T.1.0 from the marketplace for the first time, Maya 2017 and Engine v4.14. I’m just building the rig with default values, and getting the following error:

Any idea how to fix? I didn’t see an answer in this thread yet. Also, when I run the Character Rig Creator, a few pieces of the proxy character meshes have a display issue, the entire right arm and the right thigh…

Any help would be greatly appreciated!

Davidhammertime,

Not sure about the first problem you’re having, but have you made sure to update with the latest version from 's dropbox (link on first page of this thread). That helped with some starter problems I was having in Maya 2016, and the one on the marketplace is not as up-to-date.

The second issue is an easy one. It’s just a visual error and displays those pieces incorrectly in viewport 2.0. If you switch over to legacy viewport it will display the proxy meshes correctly.

kcarter,

Thanks for the reply. Viewport 2.0 issue makes sense. I did try the dropbox version as well as the marketplace version, but I am on a mac as well. I am using the mac version in the dropbox folder, but still getting errors, and a lot of the windows are too small to see all the options. I saw some fixes online for the windows being too small and buttons getting cut-off, but those fixes didn’t seem to work for me. I was having enough issues with it, that I decided to use The Setup Machine from Anzovin Studios for now, as I’ve used that auto-rigger before and it seems to be pretty stable overall.