├── CustomProceduralRiggingTool
└── CustomProceduralRigTool
│ ├── skinLib
│ ├── __init__.py
│ └── skinLib.py
│ ├── rigLib
│ ├── __init__.py
│ ├── base
│ │ ├── __init__.py
│ │ ├── controlShape
│ │ │ ├── __init__.py
│ │ │ ├── squareControl.py
│ │ │ ├── ArrowCurve.py
│ │ │ ├── unitSliderControl.py
│ │ │ ├── FootControl.py
│ │ │ ├── cubeOnBase.py
│ │ │ ├── CubeCurve.py
│ │ │ ├── Diamond.py
│ │ │ ├── SliderControl.py
│ │ │ ├── SpikeCrossControl.py
│ │ │ ├── MoveControl.py
│ │ │ ├── CrossControl.py
│ │ │ ├── FistCurve.py
│ │ │ ├── singleRotateControl.py
│ │ │ ├── CrownCurve.py
│ │ │ └── RotationControl.py
│ │ ├── module.py
│ │ └── control.py
│ ├── utils
│ │ ├── __init__.py
│ │ ├── createNode.py
│ │ ├── name.py
│ │ ├── transform.py
│ │ ├── IK_FK_Switch.py
│ │ ├── dynamicParent.py
│ │ └── joint.py
│ └── rig
│ │ ├── __init__.py
│ │ ├── Slave_Joints.py
│ │ ├── FK_Tail.py
│ │ ├── Blend_RollChain.py
│ │ ├── IK_AnimalLeg.py
│ │ ├── IK_FK_Spine.py
│ │ ├── IK_FK_Head_Neck.py
│ │ └── IK_FK_HumanArm.py
│ ├── __init__.py
│ ├── Splitter_UI.py
│ └── Edit_UI.py
├── .idea
├── vcs.xml
├── misc.xml
├── modules.xml
└── CustomProceduralRigTool.iml
└── README.md
/CustomProceduralRiggingTool/CustomProceduralRigTool/skinLib/__init__.py:
--------------------------------------------------------------------------------
1 | import skinLib
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/__init__.py:
--------------------------------------------------------------------------------
1 | import base
2 | import rig
3 | import utils
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/__init__.py:
--------------------------------------------------------------------------------
1 | import control
2 | import module
3 | import controlShape
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/__init__.py:
--------------------------------------------------------------------------------
1 | import rigLib
2 | import skinLib
3 | import Edit_UI
4 | import Main_UI
5 | import Splitter_UI
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/__init__.py:
--------------------------------------------------------------------------------
1 | import createNode
2 | import dynamicParent
3 | import IK_FK_Switch
4 | import joint
5 | import name
6 | import transform
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/__init__.py:
--------------------------------------------------------------------------------
1 | import Blend_RollChain
2 | import FK_Tail
3 | import IK_AnimalLeg
4 | import IK_FK_Head_Neck
5 | import IK_FK_HumanArm
6 | import IK_FK_Spine
7 | import Slave_Joints
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/__init__.py:
--------------------------------------------------------------------------------
1 | import ArrowCurve
2 | import CrossControl
3 | import CrownCurve
4 | import CubeCurve
5 | import cubeOnBase
6 | import Diamond
7 | import FistCurve
8 | import FootControl
9 | import MoveControl
10 | import RotationControl
11 | import singleRotateControl
12 | import SliderControl
13 | import SpikeCrossControl
14 | import unitSliderControl
15 | import squareControl
16 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/squareControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | def createShape(prefix='',
4 | scale=1.0):
5 | curve = cmds.curve(n=prefix, d=1, p=[(0, -0.5, 0.5), (0, -0.5, -0.5), (0, 0.5, -0.5), (0, 0.5, 0.5), (0, -0.5, 0.5)],
6 | k=[0, 1, 2, 3, 4])
7 | cmds.setAttr(curve + '.s', scale, scale, scale)
8 | cmds.select(cl=1)
9 |
10 | return curve
11 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/createNode.py:
--------------------------------------------------------------------------------
1 | """
2 | createNode utils @ utils
3 | """
4 | import maya.cmds as cmds
5 | def createNode(nodeStr='',
6 | prefix='',
7 | name=''):
8 |
9 | if nodeStr == 'condition':
10 | Node = cmds.createNode(nodeStr, n=prefix+name+'_CD')
11 | elif nodeStr == 'blendColors':
12 | Node = cmds.createNode(nodeStr, n=prefix+name+'_BLC')
13 | return Node
--------------------------------------------------------------------------------
/.idea/CustomProceduralRigTool.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/ArrowCurve.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 | def createShape(prefix='', scale=1.0):
3 |
4 | List = []
5 | List.append(cmds.curve(n=prefix, p=[(-1.0, 0.0, 0.0), (-1.0, 0.0, 2.0), (1.0, 0.0, 2.0), (1.0, 0.0, 0.0), (2.0, 0.0, 0.0), (0.0, 0.0, -2.0), (-2.0, 0.0, 0.0), (-1.0, 0.0, 0.0)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7]))
6 | for x in range(len(List)-1):
7 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
8 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
9 | cmds.parent(shapeNode, List[0], add=True, s=True)
10 | cmds.delete(List[x+1])
11 |
12 | sel = List[0]
13 |
14 | cmds.setAttr(sel + '.s', scale, scale, scale)
15 |
16 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
17 |
18 | return sel
19 |
20 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/name.py:
--------------------------------------------------------------------------------
1 | """
2 | name @utils
3 |
4 | Utilities to work with names and strings
5 | """
6 |
7 |
8 | def removeSuffix(name):
9 |
10 | """
11 | Remove suffix from given name string
12 | :param name: given name string to process
13 | :return: str, name without suffix
14 | """
15 |
16 | edits = name.split('_')
17 |
18 | if len(edits) < 2:
19 |
20 | return name
21 |
22 | suffix = '_' + edits[-1]
23 | nameNoSuffix = name[:-len(suffix)]
24 |
25 | return nameNoSuffix
26 |
27 |
28 | def removePrefix(name):
29 | """
30 | remove prefix
31 | :param name: str, name with no suffix
32 | :return: name with out prefix
33 | """
34 | edit = name.split('_')
35 |
36 | if len(edit) < 2:
37 | return name
38 |
39 | nameNoPrefix = edit[-1]
40 | return nameNoPrefix
41 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/unitSliderControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix=''):
5 | """
6 | create a unit slider for blend operation
7 | :param prefix: str, prefix of the control
8 | :param scale: float, scale of the control
9 | :return: str, ctrlBox of the unitSliderControl
10 | """
11 | Ctrl = cmds.circle(radius=0.2, nr=(1, 0, 0), n=prefix + '_Ctrl')[0]
12 | cmds.transformLimits(Ctrl, tx=(0, 0), ty=(0, 1), tz=(0, 0), etx=(1, 1), ety=(1, 1), etz=(1, 1))
13 |
14 | CtrlBox = cmds.curve(d=1, p=[(0, 0, 0), (0, 1, 0)], k=[0, 1], n=prefix + '_CtrlBox')
15 | parentCrvShape = cmds.listRelatives(CtrlBox, s=1)
16 | cmds.setAttr(parentCrvShape[0] + '.template', 1)
17 |
18 | cmds.parent(Ctrl, CtrlBox)
19 | cmds.makeIdentity(CtrlBox, apply=1, t=1, r=1, s=1, n=0)
20 | cmds.select(cl=1)
21 |
22 | return CtrlBox
23 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/transform.py:
--------------------------------------------------------------------------------
1 | """
2 | transform @ utils
3 |
4 | Functions to manipulate and create transforms
5 | """
6 |
7 | import maya.cmds as cmds
8 | from . import name
9 | import sys
10 | """
11 | Dir = 'C:/Users/tHeBeStXu/Documents/maya/scripts/KOMODO/code/python'
12 | if not Dir in sys.path:
13 |
14 | sys.path.append(Dir)
15 | """
16 |
17 |
18 | def makeOffsetGrp (object, prefix=''):
19 |
20 | """
21 | make offset group for given object
22 | :param object:transform object to get offset group
23 | :param prefix:str, prefix to name new objects
24 | :return:str, name of new offset group
25 | """
26 |
27 | if not prefix:
28 |
29 | prefix = name.removeSuffix(object)
30 |
31 | offsetGrp = cmds.group(n=prefix + 'Offset_grp', em=1)
32 |
33 | objectParents = cmds.listRelatives(object, p=1)
34 |
35 | if objectParents:
36 |
37 | cmds.parent(offsetGrp, objectParents[0])
38 |
39 | # match object transform
40 |
41 | cmds.delete(cmds.parentConstraint(object, offsetGrp))
42 | cmds.delete(cmds.scaleConstraint(object, offsetGrp))
43 |
44 | # parent object under offset group
45 |
46 | cmds.parent(object, offsetGrp)
47 |
48 | return offsetGrp
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CustomProceduralRigTool
2 | Custom Procedural Rig Tool for Game(Unreal)
3 | This is a procedural modular rigging tool for game, especially for Unreal Engine.
4 | Before using the script, you need to make true that your maya setup is OK for UE4.
5 | Because this is a modular rigging tool, you can use it to rig any type of creatures. For example, you can use it to rig a monster with 4
6 | arms, 2 spines and multi legs.
7 |
8 | # How to install:
9 | 1. Download the project file and unzip it somewhere in the computer, make ture to remember the directory of the unzip file location
10 | 2. Open Maya 2017+ and open script Editor
11 | 3. New a Python tab, and enter following script
12 |
13 | Dir = 'X:\WHERE\YOU\PUT\THE\FILE'
14 | import sys
15 |
16 | if Dir not in sys.path:
17 | sys.path.append(r'X:\WHERE\YOU\PUT\THE\FILE')
18 |
19 | import CustomProceduralRigTool
20 | from CustomProceduralRigTool import Main_UI as Main_UI
21 | reload(Main_UI)
22 |
23 | UI = Main_UI.RiggingMainUI(dock=1)
24 |
25 | # How to use:
26 | Please go to: https://www.bilibili.com/video/av45419722/. If you have any question, please e-mail me.
27 |
28 | # Bugs:
29 | If you find any type of bugs, please e-mail me at: 328665042@qq.com.
30 |
31 | If you like, please STAR this repository. Thank you very much.
32 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/FootControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | def createShape(prefix='', scale=1.0):
4 | List = []
5 | List.append(cmds.curve(n=prefix,p=[(0.4249371493353358, 4.798237340988468e-17, 0.05965626747485875), (0.02479363526881334, 6.785732323110913e-17, -0.3369861890540169), (-0.4476029328500644, 4.798237340988471e-17, 0.059656267474858304), (-0.16523211069250432, 1.966335461618786e-32, 0.8432678923660822), (-0.61616597431764, -4.7982373409884694e-17, 1.635912638052866), (-0.5208473195637784, -6.785732323110915e-17, 2.405743087588424), (0.606808540733522, -4.798237340988472e-17, 1.7619653609862764), (0.46646824825008704, -3.644630067904792e-32, 1.2868969494440572), (0.4249371493353358, 4.798237340988468e-17, 0.05965626747485875), (0.02479363526881334, 6.785732323110913e-17, -0.3369861890540169), (-0.4476029328500644, 4.798237340988471e-17, 0.059656267474858304)],per = True, d=3, k=[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
6 | for x in range(len(List)-1):
7 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
8 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
9 | cmds.parent(shapeNode, List[0], add=True, s=True)
10 | cmds.delete(List[x+1])
11 | cmds.select(List[0])
12 | sel = List[0]
13 | cmds.setAttr(sel + '.s', scale, scale, scale)
14 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
15 | return sel
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/Splitter_UI.py:
--------------------------------------------------------------------------------
1 | from PySide2 import QtWidgets, QtCore, QtGui
2 |
3 |
4 | class Splitter(QtWidgets.QWidget):
5 | def __init__(self, text=None):
6 | """
7 | Splitter class for create splitter widget
8 | :param text: text between splitter lines
9 | """
10 | super(Splitter, self).__init__()
11 |
12 | self.setMinimumHeight(2)
13 | self.mainLayout = QtWidgets.QHBoxLayout()
14 | self.setLayout(self.mainLayout)
15 | self.mainLayout.setContentsMargins(0, 0, 0, 0)
16 | self.mainLayout.setSpacing(0)
17 | self.mainLayout.setAlignment(QtCore.Qt.AlignVCenter)
18 |
19 | firstLine = QtWidgets.QFrame()
20 | firstLine.setFrameStyle(QtWidgets.QFrame.HLine)
21 | self.mainLayout.addWidget(firstLine)
22 |
23 | if not text:
24 | return
25 |
26 | font = QtGui.QFont()
27 | font.setBold(True)
28 |
29 | textWidth = QtGui.QFontMetrics(font)
30 | width = textWidth.width(text) + 10
31 |
32 | label = QtWidgets.QLabel()
33 | label.setText(text)
34 | label.setFont(font)
35 | label.setMaximumWidth(width)
36 | label.setAlignment(QtCore.Qt.AlignVCenter | QtCore.Qt.AlignHCenter)
37 |
38 | self.mainLayout.addWidget(label)
39 |
40 | secondLine = QtWidgets.QFrame()
41 | secondLine.setFrameStyle(QtWidgets.QFrame.HLine)
42 | self.mainLayout.addWidget(secondLine)
43 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/cubeOnBase.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n=prefix, p=[(-0.5692978297614414, 1.1385956595228828, -0.5692978297614414), (-0.5692978297614414, 1.1385956595228828, 0.5692978297614414), (0.5692978297614414, 1.1385956595228828, 0.5692978297614414), (0.5692978297614414, 1.1385956595228828, -0.5692978297614414), (-0.5692978297614414, 1.1385956595228828, -0.5692978297614414), (-0.5692978297614414, 0.0, -0.5692978297614414), (0.5692978297614414, 0.0, -0.5692978297614414), (0.5692978297614414, 1.1385956595228828, -0.5692978297614414), (0.5692978297614414, 1.1385956595228828, 0.5692978297614414), (0.5692978297614414, 0.0, 0.5692978297614414), (0.5692978297614414, 0.0, -0.5692978297614414), (-0.5692978297614414, 0.0, -0.5692978297614414), (-0.5692978297614414, 0.0, 0.5692978297614414), (0.5692978297614414, 0.0, 0.5692978297614414), (0.5692978297614414, 1.1385956595228828, 0.5692978297614414), (-0.5692978297614414, 1.1385956595228828, 0.5692978297614414), (-0.5692978297614414, 0.0, 0.5692978297614414)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]))
7 | for x in range(len(List)-1):
8 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
9 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
10 | cmds.parent(shapeNode, List[0], add=True, s=True)
11 | cmds.delete(List[x+1])
12 | sel = List[0]
13 | cmds.setAttr(sel + '.s', scale, scale, scale)
14 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
15 | return sel
16 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/CubeCurve.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | def createShape(prefix='', scale=1.0):
4 |
5 | List = []
6 | List.append(cmds.curve(n=prefix, p=[(-0.5692978297614414, 0.5692978297614414, -0.5692978297614414), (-0.5692978297614414, 0.5692978297614414, 0.5692978297614414), (0.5692978297614414, 0.5692978297614414, 0.5692978297614414), (0.5692978297614414, 0.5692978297614414, -0.5692978297614414), (-0.5692978297614414, 0.5692978297614414, -0.5692978297614414), (-0.5692978297614414, -0.5692978297614414, -0.5692978297614414), (0.5692978297614414, -0.5692978297614414, -0.5692978297614414), (0.5692978297614414, 0.5692978297614414, -0.5692978297614414), (0.5692978297614414, 0.5692978297614414, 0.5692978297614414), (0.5692978297614414, -0.5692978297614414, 0.5692978297614414), (0.5692978297614414, -0.5692978297614414, -0.5692978297614414), (-0.5692978297614414, -0.5692978297614414, -0.5692978297614414), (-0.5692978297614414, -0.5692978297614414, 0.5692978297614414), (0.5692978297614414, -0.5692978297614414, 0.5692978297614414), (0.5692978297614414, 0.5692978297614414, 0.5692978297614414), (-0.5692978297614414, 0.5692978297614414, 0.5692978297614414), (-0.5692978297614414, -0.5692978297614414, 0.5692978297614414)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]))
7 | for x in range(len(List)-1):
8 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
9 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
10 | cmds.parent(shapeNode, List[0], add=True, s=True)
11 | cmds.delete(List[x+1])
12 | cmds.select(List[0])
13 |
14 | sel = List[0]
15 |
16 | cmds.setAttr(sel + '.s', scale, scale, scale)
17 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
18 | return sel
19 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/IK_FK_Switch.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def IK_FK_Switch(prefix,
5 | switchCtrl,
6 | pvCtrl,
7 | ikCtrl,
8 | skinJoints,
9 | fkCtrlList):
10 | """
11 | IK_FK seamless switch by scriptJob and scriptNode
12 | :param prefix: str, prefix of the scriptNode
13 | :param switchCtrl: str, switchCtrl Name, usually IK_FK_Blend_Ctrl.C
14 | :param pvCtrl: str, pole vector Ctrl name.
15 | :param ikCtrl: str, IK Ctrl name
16 | :param skinJoints: list(str), list of the skin joints[shoulder, elbow, wrist]
17 | :param fkCtrlList: list(str), list of the FK Ctrl[FK_shoulder, FK_elbow, FK_wrist]
18 | :return: None
19 | """
20 | codeStr = '''
21 | import maya.cmds as cmds
22 |
23 | def switch():
24 | switchCtrl = '{0}'
25 | pvCtrl = '{1}'
26 | ikCtrl = '{2}'
27 | skinJoints = {3}
28 | fkCtrlList = {4}
29 |
30 | objAttr = switchCtrl + '.Mode'
31 | objTy = switchCtrl + '.ty'
32 | # FK 2 IK
33 | if cmds.getAttr(objAttr) == 0:
34 | cmds.matchTransform(pvCtrl, skinJoints[1], pos=1, rot=0)
35 | cmds.matchTransform(ikCtrl, skinJoints[-1], pos=1, rot=1)
36 | cmds.setAttr(objTy, 1)
37 | # IK 2 FK
38 | elif cmds.getAttr(objAttr) == 1:
39 | for i in xrange(len(skinJoints)):
40 | cmds.matchTransform(fkCtrlList[i], skinJoints[i], pos=1, rot=1)
41 | cmds.setAttr(objTy, 0)
42 |
43 | cmds.scriptJob(attributeChange=['{5}' + '.Mode', switch])
44 | '''.format(switchCtrl,
45 | pvCtrl,
46 | ikCtrl,
47 | skinJoints,
48 | fkCtrlList,
49 | switchCtrl)
50 | nodeName = cmds.scriptNode(st=2, bs=codeStr.replace("'''", "''"), n=prefix + 'Arm_IKFK_Switch_Node_#', stp='python')
51 | cmds.scriptNode(nodeName, executeBefore=1)
52 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/dynamicParent.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 | import copy
3 |
4 |
5 | def dynamicParent():
6 | sel = cmds.ls(sl=1)
7 |
8 | locatorList = []
9 | for i in xrange(len(sel)-1):
10 | locator = cmds.spaceLocator(n=sel[i] + '_Loc')
11 | cmds.delete(cmds.parentConstraint(sel[i], locator, mo=0))
12 | cmds.parent(locator, sel[i])
13 | locatorList.append(locator)
14 |
15 | DPGroup = cmds.group(n=sel[-1] + '_DPGrp', empty=1)
16 | cmds.delete(cmds.parentConstraint(sel[-1], DPGroup, mo=0))
17 |
18 | pcGroup = cmds.group(n=sel[-1] + '_pcDPGrp', empty=1)
19 | cmds.delete(cmds.parentConstraint(sel[-1], pcGroup, mo=0))
20 |
21 | cmds.parent(pcGroup, DPGroup)
22 | cmds.parent(sel[-1], pcGroup)
23 |
24 | newList = []
25 | for i in locatorList:
26 | newList.append(i[0])
27 |
28 | newList.insert(0, DPGroup)
29 |
30 | cmds.select(cl=1)
31 |
32 | for i in xrange(len(newList)):
33 | cmds.parentConstraint(newList[i], pcGroup, mo=0)
34 |
35 | parentConstraint = cmds.listRelatives(pcGroup, s=0, c=1, p=0, type='parentConstraint')[0]
36 |
37 | enumStr = ':'.join(newList)
38 | # add Attr
39 | cmds.addAttr(sel[-1], ln='Parent', at='enum', en=enumStr, k=1)
40 |
41 | for i in xrange(len(newList)):
42 | cmds.setAttr(parentConstraint + '.' + newList[i] + 'W' + str(i), 0)
43 |
44 | codeStr = '''import maya.cmds as cmds
45 |
46 | def dynamicParentSwitch():
47 | constraintObj = '{0}'
48 | parentConstraint = '{1}'
49 | newList = {2}
50 |
51 | index = cmds.getAttr(constraintObj + '.Parent')
52 |
53 | wst = cmds.xform(constraintObj, q=1, ws=1, t=1)
54 |
55 | wsr = cmds.xform(constraintObj, q=1, ws=1, ro=1)
56 |
57 | cmds.setAttr(parentConstraint + '.' + newList[index] + 'W' + str(index), 1)
58 |
59 | for i in xrange(len(newList)):
60 | if i == index:
61 | continue
62 | else:
63 | cmds.setAttr(parentConstraint + '.' + newList[i] + 'W' + str(i), 0)
64 |
65 | cmds.xform(constraintObj, ws=1, t=wst)
66 |
67 | cmds.xform(constraintObj, ws=1, ro=wsr)
68 |
69 | cmds.scriptJob(attributeChange=['{3}' + '.Parent', dynamicParentSwitch])
70 | '''.format(sel[-1],
71 | parentConstraint,
72 | newList,
73 | sel[-1])
74 | nodeName = cmds.scriptNode(st=2, bs=codeStr.replace("'''", "''"), n='DynamicParent_#', stp='python')
75 | cmds.scriptNode(nodeName, executeBefore=1)
76 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/Diamond.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n=prefix, p =[(0.0, -0.2016202582919906, 0.10123448014461145), (0.0, 1.425671083410407e-07, 0.30285488100370994), (0.20162040085909805, 1.425671083410407e-07, 0.1012344801446119), (0.0, -0.2016202582919906, 0.10123448014461145), (-0.20162040085909827, 1.425671083410407e-07, 0.1012344801446119), (0.0, 1.425671083410407e-07, 0.30285488100370994), (0.0, 0.2016202582919897, 0.1012344801446119), (-0.20162040085909827, 1.425671083410407e-07, 0.1012344801446119), (0.0, 0.2016202582919897, 0.1012344801446119), (0.20162040085909805, 1.425671083410407e-07, 0.1012344801446119), (0.0, 1.425671083410407e-07, 0.30285488100370994), (0.0, 0.2016202582919897, 0.1012344801446119), (0.0, 0.2016202582919897, -0.10134995950254133), (0.20162040085909805, -1.4256710922921911e-07, -0.101234480144611), (0.0, -0.00011562192503866697, -0.3028548810037095), (0.0, -0.2016202582919906, -0.10111900078668068), (0.20162040085909805, -1.4256710922921911e-07, -0.101234480144611), (0.20162040085909805, 1.425671083410407e-07, 0.1012344801446119), (0.0, -0.2016202582919906, 0.10123448014461145), (0.0, -0.2016202582919906, -0.10111900078668068), (-0.20162040085909827, -1.4256710922921911e-07, -0.101234480144611), (-0.20162040085909827, 1.425671083410407e-07, 0.1012344801446119), (-0.20162040085909827, -1.4256710922921911e-07, -0.101234480144611), (0.0, 0.2016202582919897, -0.10134995950254133), (0.20162040085909805, -1.4256710922921911e-07, -0.101234480144611), (0.0, -0.2016202582919906, -0.10111900078668068), (-0.20162040085909827, -1.4256710922921911e-07, -0.101234480144611), (0.0, -0.00011562192503866697, -0.3028548810037095), (0.0, -0.2016202582919906, -0.10111900078668068), (0.20162040085909805, -1.4256710922921911e-07, -0.101234480144611), (0.0, -0.00011562192503866697, -0.3028548810037095), (0.0, 0.2016202582919897, -0.10134995950254133), (-0.20162040085909827, -1.4256710922921911e-07, -0.101234480144611), (0.0, -0.00011562192503866697, -0.3028548810037095)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33]))
7 | for x in range(len(List)-1):
8 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
9 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
10 | cmds.parent(shapeNode, List[0], add=True, s=True)
11 | cmds.delete(List[x+1])
12 |
13 | sel = List[0]
14 | cmds.setAttr(sel + '.s', scale, scale, scale)
15 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
16 | return sel
17 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/SliderControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | curve6 = []
6 | curve6.append(cmds.curve(n=prefix, p =[(2.0, 0.0, 0.0), (2.0, 1.0, 0.0), (-2.0, 1.0, 0.0), (-2.0, 0.0, 0.0), (2.0, 0.0, 0.0)],per = False, d=1, k=[0, 1, 2, 3, 4]))
7 | sel1 = curve6[0]
8 | cmds.setAttr(sel1 + '.s', scale, scale, scale)
9 | cmds.makeIdentity(sel1, apply=1, t=1, r=1, s=1, n=0)
10 | curve7 = []
11 | curve7.append(cmds.curve(n=prefix, p =[(0.3506450885056627, -1.0, 0.0), (0.3506450885056627, 0.0, 0.0), (0.17532254425283136, 0.0, 0.0), (0.0, 1.0, 0.0), (-0.17532254425283136, 0.0, 0.0), (-0.3506450885056627, 0.0, 0.0), (-0.3506450885056627, -1.0, 0.0), (0.3506450885056627, -1.0, 0.0)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7]))
12 | sel2 = curve7[0]
13 | cmds.setAttr(sel2 + '.s', scale, scale, scale)
14 | cmds.makeIdentity(sel2, apply=1, t=1, r=1, s=1, n=0)
15 | cmds.parent(curve7[0], curve6[0])
16 | nurbsCircle1 = []
17 | nurbsCircle1.append(cmds.curve(n=prefix +'_ctl3', p=[(0.14113072238066665, -1.1228095718974698, 0.0), (-2.2770716313871086e-17, -1.0643513126198854, 0.0), (-0.14113072238066648, -1.1228095718974695, 0.0), (-0.1995889816582507, -1.2639402942781361, 0.0), (-0.14113072238066654, -1.4050710166588025, 0.0), (-6.014005537581757e-17, -1.463529275936387, 0.0), (0.14113072238066643, -1.4050710166588027, 0.0), (0.1995889816582507, -1.2639402942781361, 0.0), (0.14113072238066665, -1.1228095718974698, 0.0), (-2.2770716313871086e-17, -1.0643513126198854, 0.0), (-0.14113072238066648, -1.1228095718974695, 0.0)],per = True, d=3, k=[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
18 | nurbsCircle1.append(cmds.curve( p =[(0.03521960613292665, -1.4991507021320607, 0.0), (7.867936329852694e-17, -1.5282734270062825, 0.0), (-0.035219606132926545, -1.4991507021320603, 0.0), (-0.19958898165825073, -2.7041487422718746, 0.0), (-0.14113072238066654, -2.845279464652541, 0.0), (-6.014005537581757e-17, -2.9037377239301256, 0.0), (0.14113072238066643, -2.845279464652541, 0.0), (0.19958898165825073, -2.7041487422718746, 0.0), (0.03521960613292665, -1.4991507021320607, 0.0), (7.867936329852694e-17, -1.5282734270062825, 0.0), (-0.035219606132926545, -1.4991507021320603, 0.0)],per = True, d=3, k=[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
19 | for x in range(len(nurbsCircle1)-1):
20 | cmds.makeIdentity(nurbsCircle1[x+1], apply=True, t=1, r=1, s=1, n=0)
21 | shapeNode = cmds.listRelatives(nurbsCircle1[x+1], shapes=True)
22 | cmds.parent(shapeNode, nurbsCircle1[0], add=True, s=True)
23 | cmds.delete(nurbsCircle1[x+1])
24 | cmds.parent(nurbsCircle1[0], curve7[0])
25 |
26 | sel3 = nurbsCircle1[0]
27 | cmds.setAttr(sel3 + '.s', scale, scale, scale)
28 | cmds.makeIdentity(sel3, apply=1, t=1, r=1, s=1, n=0)
29 |
30 | fp = cmds.listRelatives(nurbsCircle1[0], f=True)[0]
31 | path = fp.split("|")[1]
32 |
33 |
34 | return path
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/SpikeCrossControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 |
6 | List = []
7 | List.append(cmds.curve(n=prefix, p=[(0.5698271508338371, 4.091121663662989e-09, -2.132883735050939e-05), (0.4208952391731131, 0.1488873944517639, -1.5755096100633637e-05), (0.2720931419242101, 4.073556049855043e-05, -1.0184545420344193e-05), (0.4209398007112384, -0.1487613617926744, -1.5755096101521815e-05), (0.5698271508338371, 4.091121663662989e-09, -2.132883735050939e-05), (0.42091194939155674, 6.301549556786412e-05, -0.1488401347819135), (0.2720931419242101, 4.073556049855043e-05, -1.0184545420344193e-05), (0.42092309049279564, 6.301716352297149e-05, 0.14880862458971134), (0.5698271508338371, 4.091121663662989e-09, -2.132883735050939e-05), (0.4208952391731131, 0.1488873944517639, -1.5755096100633637e-05), (0.2720931419242101, 4.073556049855043e-05, -1.0184545420344193e-05), (-0.2720931291529265, -0.0001260413294232876, 1.0184545417679658e-05), (-0.4209971894939688, -6.30282570215357e-05, 0.14884013797247952), (-0.5698271380625544, -8.530986004595675e-05, 2.1328837348733032e-05), (-0.4210083305952077, -6.302992497664306e-05, -0.1488086213991462), (-0.2720931291529265, -0.0001260413294232876, 1.0184545417679658e-05), (-0.42085456057731463, 0.14876116408473417, 1.5751905531047328e-05), (-0.5698271380625544, -8.530986004595675e-05, 2.1328837348733032e-05), (-0.4209804792755252, -0.14888740721321847, 1.575828666666723e-05), (-0.2720931291529265, -0.0001260413294232876, 1.0184545417679658e-05), (-0.2720931291529265, -0.0001260413294232876, 1.0184545417679658e-05), (0.0, -1.3322676295501878e-15, 0.0), (-1.1141101238898443e-05, -1.6679564396326896e-09, 0.2721144031802565), (0.00014271626145045957, 0.14882419235483146, 0.42093877648166433), (0.0, -1.3322676295501878e-15, 0.569763162551884), (1.671021844362741e-05, -0.14882437895619827, 0.42093878286606934), (-1.1141101238898443e-05, -1.6679564396326896e-09, 0.2721144031802565), (-0.14882987953462568, -2.2281592690021057e-05, 0.4209443534141677), (0.0, -1.3322676295501878e-15, 0.569763162551884), (0.14890412937122033, -6.29878057401001e-05, 0.42093320912223664), (-1.1141101238898443e-05, -1.6679564396326896e-09, 0.2721144031802565), (-3.151178319171777e-05, -4.717688018018862e-09, -0.2721144015837451), (-5.935678879254169e-05, 0.14882437257149927, -0.4209387812697942), (-4.265288443061621e-05, -6.385641793116292e-09, -0.5697631609553717), (-1.4801564748090357e-05, -0.1488243836738845, -0.42093878126955797), (-3.151178319171777e-05, -4.717688018018862e-09, -0.2721144015837451), (-0.1488613913178174, -2.2286310378039076e-05, -0.4209332107214614), (-4.265288443061621e-05, -6.385641793116292e-09, -0.5697631609553717), (0.1488726175880286, -6.299252342767403e-05, -0.42094435501339156), (-3.151178319171777e-05, -4.717688018018862e-09, -0.2721144015837451)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]))
8 | for x in range(len(List)-1):
9 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
10 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
11 | cmds.parent(shapeNode, List[0], add=True, s=True)
12 | cmds.delete(List[x+1])
13 | sel = List[0]
14 | cmds.setAttr(sel + '.s', scale, scale, scale)
15 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
16 | return sel
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/Slave_Joints.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def build(inputJoints=None):
5 | """
6 | create Slave joints for given joints list.
7 | if inputJoints = None, create slave joints for all joints in the scene without end joint in the joint chain
8 | :param inputJoints: str list, target joints list for create Slave joints
9 | :return: None
10 | """
11 |
12 | if inputJoints:
13 | targetJoints = inputJoints
14 | else:
15 | targetJoints = []
16 |
17 | # list all selected inputJoints without end inputJoints
18 | allJoints = cmds.ls(type='joint')
19 | for joint in allJoints:
20 | if cmds.attributeQuery('slaveJoint', node=joint, exists=1):
21 | targetJoints.append(joint)
22 |
23 | cmds.select(cl=1)
24 |
25 | # 1. generate slave joint for each target joint
26 |
27 | if targetJoints:
28 | for joint in targetJoints:
29 | slaveJoint = cmds.joint(n='Slave_' + joint)
30 | cmds.select(cl=1)
31 |
32 | cmds.delete(cmds.parentConstraint(joint, slaveJoint, mo=0))
33 | cmds.makeIdentity(slaveJoint, apply=1, t=1, r=1, s=1)
34 |
35 | if not cmds.attributeQuery('slaveJoint', node=slaveJoint, exists=1):
36 | cmds.addAttr(slaveJoint, ln='slaveJoint', at='message')
37 |
38 | cmds.connectAttr(joint + '.slaveJoint', slaveJoint + '.slaveJoint', f=1)
39 |
40 | cmds.select(cl=1)
41 |
42 | # 2. parenting
43 |
44 | if targetJoints:
45 | for joint in targetJoints:
46 | slaveJoint = cmds.listConnections(joint + '.slaveJoint', destination=1, source=0, type='joint')[0]
47 |
48 | if cmds.attributeQuery('slaveParent', node=joint, exists=1):
49 | parent = cmds.getAttr(joint + '.slaveParent')
50 |
51 | if cmds.attributeQuery('slaveJoint', node=parent, exists=1):
52 | parentSlave = cmds.listConnections(parent + '.slaveJoint', source=0, destination=1, type='joint')[0]
53 |
54 | if parentSlave:
55 | cmds.parent(slaveJoint, parentSlave)
56 |
57 | else:
58 | parent = cmds.listRelatives(joint, c=0, p=1, s=0, type='joint', path=1)
59 | if parent:
60 | if cmds.attributeQuery('slaveJoint', node=parent[0], exists=1):
61 | parentSlave = cmds.listConnections(parent[0] + '.slaveJoint',
62 | source=0, destination=1, type='joint')
63 |
64 | if parentSlave:
65 | cmds.parent(slaveJoint, parentSlave[0])
66 |
67 | cmds.select(cl=1)
68 |
69 | # 3. Constraint slave joint
70 |
71 | if targetJoints:
72 | for joint in targetJoints:
73 | slaveJoint = cmds.listConnections(joint + '.slaveJoint', destination=1, source=0, type='joint')[0]
74 |
75 | if cmds.attributeQuery('slavePointConst', node=joint, exists=1):
76 | pointConst = cmds.getAttr(joint + '.slavePointConst')
77 |
78 | if pointConst:
79 | cmds.pointConstraint(pointConst, slaveJoint, mo=0)
80 | else:
81 | cmds.pointConstraint(joint, slaveJoint, mo=0)
82 |
83 | cmds.orientConstraint(joint, slaveJoint, mo=0)
84 | cmds.scaleConstraint(joint, slaveJoint, mo=0)
85 |
86 | cmds.select(cl=1)
87 |
88 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/MoveControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n=prefix, p =[(-0.3839938634902286, 4.2573685351256776e-17, -0.6952810456190021), (-0.4493179344379141, 4.038083501531363e-17, -0.6594690819169796), (-0.5699654669930883, 3.490031924607386e-17, -0.5699654671105632), (-0.6594690818169142, 2.7512788518703874e-17, -0.4493179345727984), (-0.6952810454988885, 2.3512842804192566e-17, -0.38399386370932614)],per = False, d=3, k=[0, 0, 0, 1, 2, 2, 2]))
7 | List.append(cmds.curve( p =[(-1.1519815904477793, 0.0, -0.38399386348259285), (-1.1519815904477793, 0.0, -0.7679877269651857), (-1.9199693174129653, 0.0, 0.0), (-1.1519815904477793, 0.0, 0.7679877269651857), (-1.1519815904477793, 0.0, 0.38399386348259285), (-0.6952810455459, 0.0, 0.38399386348259285)],per = False, d=1, k=[0, 1, 2, 3, 4, 5]))
8 | List.append(cmds.curve( p =[(-0.6952810454988887, -2.351284280419254e-17, 0.38399386370932576), (-0.6594690818169144, -2.7512788518703853e-17, 0.44931793457279806), (-0.5699654670431211, -3.490031924194421e-17, 0.5699654670431209), (-0.4493179345727985, -4.03808350091864e-17, 0.6594690818169142), (-0.38399386370932614, -4.2573685343901955e-17, 0.6952810454988885)],per = False, d=3, k=[0, 0, 0, 1, 2, 2, 2]))
9 | List.append(cmds.curve( p =[(0.38399386370932587, -4.257368534390195e-17, 0.6952810454988885), (0.44931793457279817, -4.03808350091864e-17, 0.6594690818169143), (0.5699654670431207, -3.4900319241944226e-17, 0.569965467043121), (0.659469081816914, -2.7512788518703884e-17, 0.4493179345727986), (0.6952810454988883, -2.3512842804192578e-17, 0.38399386370932637)],per = False, d=3, k=[0, 0, 0, 1, 2, 2, 2]))
10 | List.append(cmds.curve( p =[(0.6952810454988887, 2.351284280419254e-17, -0.3839938637093257), (0.6594690818169145, 2.751278851870385e-17, -0.44931793457279795), (0.5699654670431213, 3.4900319241944195e-17, -0.5699654670431206), (0.44931793457279867, 4.0380835009186384e-17, -0.659469081816914), (0.38399386370932637, 4.2573685343901936e-17, -0.6952810454988883)],per = False, d=3, k=[0, 0, 0, 1, 2, 2, 2]))
11 | List.append(cmds.curve( p =[(-0.38399386348259307, 0.0, 0.6952810455458994), (-0.38399386348259307, 0.0, 1.1519815904477788), (-0.7679877269651861, 0.0, 1.1519815904477788), (0.0, 0.0, 1.919969317412964), (0.7679877269651861, 0.0, 1.1519815904477788), (0.38399386348259307, 0.0, 1.1519815904477788), (0.38399386348259307, 0.0, 0.6952810463138872)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6]))
12 | List.append(cmds.curve( p =[(0.6952810463138878, 0.0, 0.38399386348259285), (1.1519815904477793, 0.0, 0.38399386348259285), (1.1519815904477793, 0.0, 0.7679877269651857), (1.9199693174129653, 0.0, 0.0), (1.1519815904477793, 0.0, -0.7679877269651857), (1.1519815904477793, 0.0, -0.38399386348259285), (0.6952810463138878, 0.0, -0.38399386348259285)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6]))
13 | List.append(cmds.curve( p =[(0.38399386348259307, 0.0, -0.6952810463138872), (0.38399386348259307, 0.0, -1.1519815904477788), (0.7679877269651861, 0.0, -1.1519815904477788), (0.0, 0.0, -1.919969317412964), (-0.7679877269651861, 0.0, -1.1519815904477788), (-0.38399386348259307, 0.0, -1.1519815904477788), (-0.38399386348259307, 0.0, -0.6952810463138872)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6]))
14 | List.append(cmds.curve( p =[(-0.6952810463138878, 0.0, -0.38399386348259285), (-1.1519815904477793, 0.0, -0.38399386348259285)],per = False, d=1, k=[0, 1]))
15 | for x in range(len(List)-1):
16 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
17 | shapeNode = cmds.listRelatives(List[x+1], shapes=True)
18 | cmds.parent(shapeNode, List[0], add=True, s=True)
19 | cmds.delete(List[x+1])
20 | sel = List[0]
21 | cmds.setAttr(sel + '.s', scale, scale, scale)
22 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
23 |
24 | return sel
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/utils/joint.py:
--------------------------------------------------------------------------------
1 | """
2 | joint utils @ utils
3 | """
4 |
5 | import maya.cmds as cmds
6 | from . import name
7 |
8 |
9 | def listHierarchy(topJoint,
10 | withEndJoints=True):
11 |
12 | """
13 | list joint hierarchy starting with top joint
14 | :param topJoint: str, joint to get listed with its joint hierarchy
15 | :param withEndJoints: bool, list hierarchy including end joints
16 | :return: list(str), listed joints starting with top joint
17 | """
18 |
19 | listedJoints = cmds.listRelatives(topJoint,
20 | type='joint',
21 | ad=1)
22 | listedJoints.append(topJoint)
23 | listedJoints.reverse()
24 |
25 | completeJoints = listedJoints[:]
26 |
27 | if not withEndJoints:
28 |
29 | completeJoints = [j for j in listedJoints if cmds.listRelatives(j, c=1, type='joint')]
30 |
31 | return completeJoints
32 |
33 |
34 |
35 | def createRevJnts(revLocator,
36 | orientCtrl,
37 | suffix):
38 | """
39 | create revJnts for IK
40 | :param revLocator: list(str), ['CBank_LOC','EBank_LOC','heel_LOC'...]
41 | :param orientCtrl:
42 | :return: list(str),revJntChain
43 | """
44 |
45 | # create joints for each LOC with correct name and orientation
46 | revJoints=[]
47 | for loc in revLocator:
48 | revJnt = cmds.joint(n=name.removeSuffix(loc) + suffix)
49 | cmds.delete(cmds.orientConstraint(orientCtrl, loc, mo=0))
50 | cmds.delete(cmds.pointConstraint(loc, revJnt, mo=0))
51 | revJoints.append(revJnt)
52 |
53 | return revJoints
54 |
55 |
56 | def createFKjnts(CurveCVs,
57 | orientObj,
58 | prefix):
59 | """
60 | create FK Joints by Specified curveCVs
61 | :param CurveCVs: list(str), CurveCVs in builder Curve
62 | :param orientJnt: str, orient Object
63 | :param prefix: str, prefix of FK joints
64 | :return: list(str), list of FKjoints chain
65 | """
66 | fkJoints = []
67 | fkClusters = []
68 |
69 | for i in range(len(CurveCVs)):
70 | cls = cmds.cluster(CurveCVs[i], n=prefix + 'Cluster%d' % (i+1))[1]
71 | cmds.hide(cls)
72 | fkJnt = cmds.joint(n=prefix + '_FK%d' % i)
73 | cmds.delete(cmds.orientConstraint(orientObj, fkJnt, mo=0))
74 | cmds.delete(cmds.pointConstraint(cls, fkJnt, mo=0))
75 | fkJoints.append(fkJnt)
76 | fkClusters.append(cls)
77 |
78 | for i in range((len(fkJoints)-1)):
79 | cmds.parent(fkJoints[i+1], fkJoints[i])
80 |
81 | return {'fkJoints': fkJoints, 'fkClusters': fkClusters}
82 |
83 |
84 | def dupSpecifiedJnts(startDupJnt,
85 | endDupJnt,
86 | suffix):
87 | dupDirtyJnt = cmds.duplicate(startDupJnt, n=startDupJnt + suffix)
88 | dupFullPath = cmds.listRelatives(dupDirtyJnt[0], f=1, ad=1)
89 | # remove endJnt Children
90 | for jnt in dupFullPath:
91 | if endDupJnt in jnt:
92 | if (len(endDupJnt) + jnt.index(endDupJnt)) < len(jnt):
93 | cmds.removeJoint(jnt)
94 |
95 |
96 | # rename cleanJnt
97 | dupCleanJnt = cmds.listRelatives(dupDirtyJnt[0], ad=1, f=1)
98 | for Jnt in dupCleanJnt:
99 | cmds.select(Jnt, add=1)
100 | for sel in cmds.ls(sl=1):
101 | cmds.rename(sel, sel.split('|')[-1] + suffix)
102 |
103 | dupCleanJnt = cmds.listRelatives(dupDirtyJnt[0], ad=1, f=1)
104 | dupCleanJnt = appendAndReverse(addtargetEndJnt=dupDirtyJnt[0], reverseList=dupCleanJnt)
105 |
106 | # clean returnList
107 | finalJnts = listHierarchy(topJoint=dupCleanJnt[0])
108 |
109 | return finalJnts
110 |
111 |
112 | def appendAndReverse(addtargetEndJnt='',reverseList=''):
113 | reverseList.append(addtargetEndJnt)
114 | reverseList.reverse()
115 | return reverseList
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/CrossControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n=prefix, p=[(11.65040520317079, 0.0, -1.0753491255960874), (11.260327870011457, 0.0, -1.0753491255960874), (10.919827839642535, 0.0, -0.8669835460599025), (10.731345094628578, 0.0, -0.5561779839591772), (8.827645335077547, 0.0, -0.7404428130644156), (1.7165524628499949, 0.0, -0.7404428130644156), (0.7006951136854465, 0.0, -0.7404428130644156), (0.7006951136854465, 0.0, -1.7563012592434397), (0.7006951136854465, 3.552713678800501e-15, -8.867401810671094), (0.7006951136854465, 3.552713678800501e-15, -9.883260256850125), (1.1144722701987622, 3.552713678800501e-15, -10.134188373311648), (1.391870513759761, 3.552713678800501e-15, -10.587497938965694), (1.391870513759761, 3.552713678800501e-15, -11.106800167630926), (1.391870513759761, 3.552713678800501e-15, -11.897477970132908), (0.7509301031230269, 3.552713678800501e-15, -12.538418380769645), (-0.03974769937895495, 3.552713678800501e-15, -12.538418380769645), (-0.8304255018809439, 3.552713678800501e-15, -12.538418380769645), (-1.471365912517678, 3.552713678800501e-15, -11.897477970132908), (-1.471365912517678, 3.552713678800501e-15, -11.106800167630926), (-1.471365912517678, 3.552713678800501e-15, -10.587547305110977), (-1.1939775421857295, 3.552713678800501e-15, -10.134237739456932), (-0.78023987858864, 3.552713678800501e-15, -9.883260256850125), (-0.78023987858864, 3.552713678800501e-15, -8.867401810671094), (-0.78023987858864, 0.0, -1.7563012592434397), (-0.78023987858864, 0.0, -0.7404428130644156), (-1.7960928396952713, 0.0, -0.7404428130644156), (-8.907154995122445, 0.0, -0.7404428130644156), (-11.001958686483563, 0.0, -0.4807034302220181), (-11.164895964918708, 0.0, -0.7493320062227404), (-11.459189405705198, 0.0, -0.9294219265576693), (-11.796332402209199, 0.0, -0.9294219265576693), (-12.309648927343797, 0.0, -0.9294219265576693), (-12.72575432876686, 0.0, -0.5133165251346163), (-12.72575432876686, 0.0, -1.7763568394002505e-14), (-12.72575432876686, 0.0, 0.5133165251345808), (-12.309648927343797, 0.0, 0.9294219265576551), (-11.796332402209199, 0.0, 0.9294219265576551), (-11.459221454737152, 0.0, 0.9294219265576551), (-11.164928013950659, 0.0, 0.7493320062227262), (-11.00199073551551, 0.0, 0.4807354792539478), (-8.907198876195322, 0.0, 0.7404921792096708), (-1.7960983247676712, 0.0, 0.7404921792096708), (-0.78023987858864, 0.0, 0.7404921792096708), (-0.78023987858864, 0.0, 1.7563451403163022), (-0.78023987858864, -3.552713678800501e-15, 8.86740729574348), (-0.78023987858864, -3.552713678800501e-15, 9.883260256850118), (-1.194026908331006, -3.552713678800501e-15, 10.134188373311627), (-1.471415278662958, -3.552713678800501e-15, 10.587497938965694), (-1.471415278662958, -3.552713678800501e-15, 11.106800167630926), (-1.471415278662958, -3.552713678800501e-15, 11.8974779701329), (-0.830474868026224, -3.552713678800501e-15, 12.538418380769645), (-0.03979706552423856, -3.552713678800501e-15, 12.538418380769645), (0.7508807369777433, -3.552713678800501e-15, 12.538418380769645), (1.3918211476144808, -3.552713678800501e-15, 11.8974779701329), (1.3918211476144808, -3.552713678800501e-15, 11.106800167630926), (1.3918211476144808, -3.552713678800501e-15, 10.587547305110963), (1.114422904053475, -3.552713678800501e-15, 10.134237739456903), (0.7006951136854465, -3.552713678800501e-15, 9.883260256850118), (0.7006951136854465, -3.552713678800501e-15, 8.86740729574348), (0.7006951136854465, 0.0, 1.7563451403163022), (0.7006951136854465, 0.0, 0.7404921792096708), (1.7165524628499949, 0.0, 0.7404921792096708), (8.827645335077547, 0.0, 0.7404921792096708), (10.731345094628578, 0.0, 0.556215064963471), (10.919864920646871, 0.0, 0.866983546059874), (11.260364951015786, 0.0, 1.075349125596059), (11.65040520317079, 0.0, 1.075349125596059), (12.244316817137067, 0.0, 1.075349125596059), (12.72575432876686, 0.0, 0.5939116139662737), (12.72575432876686, 0.0, -1.7763568394002505e-14), (12.72575432876686, 0.0, -0.593911613966295), (12.244316817137067, 0.0, -1.0753491255960874), (11.65040520317079, 0.0, -1.0753491255960874)],per = False, d=3, k=[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24]))
7 | for x in range(len(List)-1):
8 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
9 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
10 | cmds.parent(shapeNode, List[0], add=True, s=True)
11 | cmds.delete(List[x+1])
12 |
13 | #print List[0]
14 | sel = List[0]
15 |
16 | cmds.setAttr(sel + '.s', scale, scale, scale)
17 |
18 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
19 |
20 | return sel
21 |
22 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/FK_Tail.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | from ..base import control
4 | from ..base import module
5 | reload(control)
6 | reload(module)
7 |
8 |
9 | def build(tailJoints,
10 | FK_Parent='',
11 | rigScale=1.0,
12 | prefix='C_',
13 | baseRig=None
14 | ):
15 | """
16 | Build the FK_Tail rig.
17 | :param tailJoints: list(str), tailJoints to the end. i.e.[tail_1, tail_2, tail_3, ... tail_x, tail_end]
18 | :param rigScale: float, rig scale of the FK_Tail rig module, 1.0 is used.
19 | :param FK_Parent: str, the joint which tailJoint[0] connects to.
20 | :param prefix: str, prefix of the tail rig.
21 | :param baseRig: str, base atttach of the rig, Base Class instance is used.
22 | :return: None
23 | """
24 | rigPartName = 'Tail'
25 |
26 | cmds.select(cl=1)
27 | rigModule = module.Module(prefix=prefix,
28 | rigPartName=rigPartName,
29 | baseObject=baseRig)
30 |
31 | ##########
32 | # FK Rig #
33 | ##########
34 | validTailJoints = []
35 | for i in tailJoints:
36 | if cmds.listRelatives(i, s=0, p=0, children=1):
37 | validTailJoints.append(i)
38 |
39 | FK_tailCtrl_List = []
40 | FK_tailCtrlGrp_List = []
41 |
42 | # FK Ctrl
43 | for i in xrange(len(validTailJoints)):
44 | FK_tailCtrl = control.Control(prefix=prefix + 'FK_',
45 | rigPartName=rigPartName + '_' + str(i),
46 | scale=rigScale * (len(validTailJoints) - i),
47 | translateTo=validTailJoints[i],
48 | rotateTo=validTailJoints[i],
49 | shape='circle')
50 |
51 | cmds.pointConstraint(FK_tailCtrl.C, validTailJoints[i], mo=0)
52 | cmds.orientConstraint(FK_tailCtrl.C, validTailJoints[i], mo=0)
53 |
54 | FK_tailCtrl_List.append(FK_tailCtrl.C)
55 | FK_tailCtrlGrp_List.append(FK_tailCtrl.Off)
56 |
57 | cmds.select(cl=1)
58 |
59 | # Parenting
60 | for i in xrange(len(FK_tailCtrlGrp_List)-1):
61 | cmds.parent(FK_tailCtrlGrp_List[i+1], FK_tailCtrl_List[i])
62 |
63 | cmds.select(cl=1)
64 |
65 | # add and set ctrl visibility
66 | cmds.addAttr(FK_tailCtrl_List[0], ln='Tail_Ctrl_Visibility', at='bool', dv=0, k=1)
67 |
68 | target_Ctrl_List = []
69 | for i in FK_tailCtrl_List[1::2]:
70 | target_Ctrl_List.append(i)
71 |
72 | ctrlShape_Input_List = []
73 | for i in xrange(len(target_Ctrl_List)):
74 | CtrlShape = cmds.listRelatives(target_Ctrl_List[i], s=1, children=0, parent=0)
75 | ctrlShape_Input = cmds.listConnections(CtrlShape[0] + '.create', source=1, destination=0, plugs=0)[0]
76 | ctrlShape_Input_List.append(ctrlShape_Input)
77 |
78 | cmds.setAttr(FK_tailCtrl_List[0] + '.Tail_Ctrl_Visibility', 0)
79 | for i in xrange(len(ctrlShape_Input_List)):
80 | cmds.setAttr(ctrlShape_Input_List[i] + '.sweep', 0)
81 | cmds.setDrivenKeyframe(ctrlShape_Input_List[i] + '.sweep', cd=FK_tailCtrl_List[0] + '.Tail_Ctrl_Visibility')
82 |
83 | cmds.setAttr(FK_tailCtrl_List[0] + '.Tail_Ctrl_Visibility', 1)
84 | for i in xrange(len(ctrlShape_Input_List)):
85 | cmds.setAttr(ctrlShape_Input_List[i] + '.sweep', 360)
86 | cmds.setDrivenKeyframe(ctrlShape_Input_List[i] + '.sweep', cd=FK_tailCtrl_List[0] + '.Tail_Ctrl_Visibility')
87 |
88 | # Clean the hierarchy
89 | if FK_Parent:
90 | FK_Loc = cmds.spaceLocator(n=prefix + 'Tail_Loc')
91 | FK_LocShape = cmds.listRelatives(FK_Loc, s=1)
92 | cmds.setAttr(FK_LocShape[0] + '.localScaleX', 0)
93 | cmds.setAttr(FK_LocShape[0] + '.localScaleY', 0)
94 | cmds.setAttr(FK_LocShape[0] + '.localScaleZ', 0)
95 | cmds.parentConstraint(FK_Parent, FK_Loc, mo=0)
96 | cmds.parent(FK_tailCtrlGrp_List[0], FK_Loc)
97 | cmds.parent(FK_Loc, rigModule.topGrp)
98 | else:
99 | cmds.parent(FK_tailCtrlGrp_List[0], rigModule.topGrp)
100 | cmds.warning('Warning: FK_Parent is None!')
101 |
102 | cmds.select(cl=1)
103 |
104 | # add attr
105 | for joint in tailJoints[:-1]:
106 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
107 | cmds.addAttr(joint, longName='slaveJoint', at='message')
108 |
109 | if not cmds.attributeQuery('rigModule', node=joint, exists=1):
110 | cmds.addAttr(joint, longName='rigModule', at='message')
111 |
112 | # connect attr
113 | for joint in tailJoints[:-1]:
114 | if cmds.attributeQuery('rigModule', node=joint, exists=1):
115 | cmds.connectAttr(rigModule.topGrp + '.' + prefix + 'Tail_Jnt',
116 | joint + '.rigModule', f=1)
117 |
118 | cmds.select(cl=1)
119 |
120 | return rigModule
121 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/FistCurve.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='',scale=1.0):
5 | curveList = []
6 | curveList.append(cmds.curve(n=prefix, p=[(-0.28323181266160297, 0.000406980572728477, 0.28089025488631625), (-0.27202045445878775, 0.00040578537807589576, 0.30675169764711463), (-0.16198898578534848, 0.0002959027012675586, 0.31719778364300344), (-0.14166430519302461, 0.0002638997858650516, 0.2901035131433195), (-0.12271829303889557, 0.00025713970399843245, 0.3220531749715917), (0.02713533575627433, 9.83968965067028e-05, 0.3137370793648865), (0.03176093037293855, 8.173089445495663e-05, 0.28430702611824754), (0.056749199967236874, 6.637965130906753e-05, 0.3104901640897325), (0.16751595847437994, -5.696587005177278e-05, 0.28944615284404496), (0.18015194072999668, -8.424532602469004e-05, 0.2542955321992887), (0.20724620736689808, -0.00010414314516615786, 0.27462023339664776), (0.3207623415211349, -0.0002438152315058506, 0.22016395029045432), (0.3173775484988463, -0.0002498677796364257, 0.1964544644419327), (0.28905840272616196, -0.0002755696144985942, 0.05991811674892045), (0.1866776380041197, -0.00020372807142798877, -0.025179080819704547), (0.12323791549698926, -0.00013060042904178282, -0.006968376721144698), (0.12676057536309723, -0.00012707216426488532, 0.010836715894581128), (0.16986765604860782, -0.000134037789155661, 0.10439587509111237), (0.18015194072999668, -8.424532602469004e-05, 0.2542955321992887), (0.16986765604860782, -0.000134037789155661, 0.10439587509111237), (0.12676057536309723, -0.00012707216426488532, 0.010836715894581128), (0.09568409271402309, -0.00010228833205516707, -0.007611767142518655), (0.0024926391521100932, 5.380838882240724e-06, 0.019750245463990623), (0.002033083006045003, 1.3795116727499668e-05, 0.039431556239976184), (0.038684305719927634, 2.2993503176693686e-05, 0.15647041899168113), (0.03176093037293855, 8.173089445495663e-05, 0.28430702611824754), (0.038684305719927634, 2.2993503176693686e-05, 0.15647041899168113), (0.002033083006045003, 1.3795116727499668e-05, 0.039431556239976184), (-0.015266488251546056, 2.4422900443799023e-05, 0.021304768413563324), (-0.11010438270999656, 0.00012822436953141558, 0.03484390701821305), (-0.11656024068162453, 0.0001443883808714963, 0.058323610573386975), (-0.11519749470202205, 0.00018746375152134398, 0.16863086383624448), (-0.1374982667224255, 0.00025564806165856435, 0.280354770672666), (-0.11519749470202205, 0.00018746375152134398, 0.16863086383624448), (-0.11656024068162453, 0.0001443883808714963, 0.058323610573386975), (-0.13559816406496666, 0.00015283131830712282, 0.03031021090031183), (-0.21780007626780026, 0.0002293533314217111, 0.008698728860205285), (-0.24755180732258217, 0.00026389485997291295, 0.017850037368154714), (-0.27228026568783414, 0.0003425157405972934, 0.14920929852189213), (-0.28323181266160297, 0.000406980572728477, 0.28089025488631625), (-0.27228026568783414, 0.0003425157405972934, 0.14920929852189213), (-0.25789819488421134, 0.00029678983827530203, 0.0728107553244185), (-0.2892042307992774, 0.00031225299994463995, 0.030661869279283938), (-0.3242010513873258, 0.0002727632132523139, -0.1572297122659686), (-0.2025287015210206, 8.579428754484919e-05, -0.307986548798482), (-0.1452231476832722, 2.2940662007031598e-05, -0.31649446688505767), (-0.2025287015210206, 8.579428754484919e-05, -0.307986548798482), (-0.3242010513873258, 0.0002727632132523139, -0.1572297122659686), (-0.2892042307992774, 0.00031225299994463995, 0.030661869279283938), (-0.25789819488421134, 0.00029678983827530203, 0.0728107553244185), (-0.12425690024762795, 0.0001832709423938983, 0.13494285322372146), (-0.09665712185005507, 0.00015411741762272335, 0.13361811256749678), (-0.0613147282718725, 8.523990354458721e-05, 0.053705998183338766), (-0.0924751609208636, 7.754748923050059e-05, -0.04548181549397079), (-0.2134422541094789, 0.00018357679398428584, -0.09359813071624934), (-0.21421553832849324, 0.0001637219642284249, -0.14481549519248105), (-0.2134422541094789, 0.00018357679398428584, -0.09359813071624934), (-0.0924751609208636, 7.754748923050059e-05, -0.04548181549397079), (-0.06916367857107959, 8.330227391306622e-05, 0.02872174239299352), (-0.015266488251546056, 2.4422900443799023e-05, 0.021304768413563324), (0.002033083006045003, 1.3795116727499668e-05, 0.039431556239976184), (0.0024926391521100932, 5.380838882240724e-06, 0.019750245463990623), (0.09568409271402309, -0.00010228833205516707, -0.007611767142518655), (0.12676057536309723, -0.00012707216426488532, 0.010836715894581128), (0.12323791549698926, -0.00013060042904178282, -0.006968376721144698), (0.1866776380041197, -0.00020372807142798877, -0.025179080819704547), (0.28905840272616196, -0.0002755696144985942, 0.05991811674892045), (0.30292048871058846, -0.0002629886896473588, 0.1267520038623421), (0.32760176686820724, -0.0003350288693079184, 0.01158801252367836), (0.295951744917137, -0.00040178378217803346, -0.23530154489086097), (0.20931602178536124, -0.00034612058024263703, -0.3200310907901296), (0.14436772522551244, -0.0002793849230598999, -0.32154765392622486)],per = False, d=1, k=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71]))
7 | for x in range(len(curveList)-1):
8 | cmds.makeIdentity(curveList[x+1], apply=True, t=1, r=1, s=1, n=0)
9 | shapeNode = cmds.curveListRelatives(curveList[x+1], shapes=True)
10 | cmds.parent(shapeNode, curveList[0], add=True, s=True)
11 | cmds.delete(curveList[x+1])
12 | sel = curveList[0]
13 | cmds.setAttr(sel + '.s', scale, scale, scale)
14 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
15 | return sel
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/module.py:
--------------------------------------------------------------------------------
1 | """
2 | module for making top rig structure and rig module
3 | """
4 |
5 | import maya.cmds as cmds
6 | import control
7 | reload(control)
8 |
9 | sceneObjectType = 'rig'
10 |
11 |
12 | class Base():
13 | """
14 | class for building top rig structure
15 | """
16 |
17 | @classmethod
18 | def addAttr(cls, group):
19 | if group:
20 | if not cmds.attributeQuery('MasterCtrl', node=group, exists=1):
21 | cmds.addAttr(group, ln='MasterCtrl', at='message')
22 |
23 | if not cmds.attributeQuery('MoveCtrl', node=group, exists=1):
24 | cmds.addAttr(group, ln='MoveCtrl', at='message')
25 |
26 | if not cmds.attributeQuery('rigModule', node=group, exists=1):
27 | cmds.addAttr(group, ln='rigModule', at='message')
28 |
29 | def __init__(self,
30 | characterName='new',
31 | scale=1.0,
32 | mainCtrlAttachObj=''
33 | ):
34 | """
35 | :param characterName: str, character name
36 | :param scale: float, general scale of the rig
37 | :return None
38 | """
39 |
40 | self.topGrp = cmds.group(n=characterName, em=1)
41 |
42 | characterNameAttr = 'characterName'
43 | sceneObjectTypeAttr = 'sceneObjectType'
44 |
45 | for attr in [characterNameAttr, sceneObjectTypeAttr]:
46 |
47 | cmds.addAttr(self.topGrp, ln=attr, dt='string')
48 |
49 | cmds.setAttr(self.topGrp + '.' + characterNameAttr,
50 | characterName, type='string', l=1)
51 | cmds.setAttr(self.topGrp + '.' + sceneObjectTypeAttr,
52 | sceneObjectType, type='string', l=1)
53 |
54 | # make global control
55 |
56 | self.Master_Ctrl = control.Control(prefix='C_',
57 | rigPartName='Master',
58 | shape='crownCurve',
59 | scale=scale * 10.0,
60 | parent=self.topGrp,
61 | axis='z',
62 | lockChannels=['v'])
63 |
64 | if not cmds.attributeQuery('MasterCtrl', node=self.Master_Ctrl.C, exists=1):
65 | cmds.addAttr(self.Master_Ctrl.C, ln='MasterCtrl', at='message')
66 |
67 | self.Move_Ctrl = control.Control(prefix='C_',
68 | rigPartName='Move',
69 | shape='moveControl',
70 | scale=scale * 15.0,
71 | parent=self.Master_Ctrl.C,
72 | axis='z',
73 | lockChannels=['s', 'v'])
74 |
75 | if not cmds.attributeQuery('MoveCtrl', node=self.Move_Ctrl.C, exists=1):
76 | cmds.addAttr(self.Move_Ctrl.C, ln='MoveCtrl', at='message')
77 |
78 | # add Attr
79 | if not cmds.attributeQuery('slaveJoint', node=self.Move_Ctrl.C, exists=1):
80 | cmds.addAttr(self.Move_Ctrl.C, ln='slaveJoint', at='message')
81 |
82 | if not cmds.attributeQuery('rootJoint', node=self.Move_Ctrl.C, exists=1):
83 | cmds.addAttr(self.Move_Ctrl.C, ln='rootJoint', at='message')
84 |
85 | for axis in ['y', 'z']:
86 |
87 | cmds.connectAttr(self.Master_Ctrl.C + '.sx', self.Master_Ctrl.C + '.s' + axis)
88 | cmds.setAttr(self.Master_Ctrl.C + '.s' + axis, k=0)
89 |
90 | cmds.aliasAttr('Global_Scale', self.Master_Ctrl.C + '.sx')
91 |
92 | # create a grp for objects are not influenced by rig moving
93 | self.dontTouchGrp = cmds.group(n='Dont_Touch_Grp', em=1, p=self.topGrp)
94 | # lock the inherits Transform attr
95 | cmds.setAttr(self.dontTouchGrp + '.it', 0, l=1)
96 |
97 | cmds.select(cl=1)
98 |
99 | # create setting group for further operation
100 | self.settingGrp = cmds.group(n=characterName + '_SettingGrp', em=1, p=self.dontTouchGrp)
101 |
102 | # add attrs to setting group
103 | Base.addAttr(group=self.settingGrp)
104 |
105 | # connect attr
106 | cmds.connectAttr(self.settingGrp + '.MasterCtrl',
107 | self.Master_Ctrl.C + '.MasterCtrl', f=1)
108 |
109 | cmds.connectAttr(self.settingGrp + '.MoveCtrl',
110 | self.Move_Ctrl.C + '.MoveCtrl', f=1)
111 |
112 |
113 | class Module():
114 |
115 | """class for building module rig structure"""
116 |
117 | @classmethod
118 | def addAttr(cls, group):
119 | # query and add attribute
120 | if group:
121 | if not cmds.attributeQuery('slaveJoint', node=group, exists=1):
122 | cmds.addAttr(group, longName='slaveJoint', at='message')
123 |
124 | if not cmds.attributeQuery('settingGrp', node=group, exists=1):
125 | cmds.addAttr(group, longName='settingGrp', at='message')
126 |
127 | def __init__(self,
128 | prefix='L_',
129 | rigPartName='',
130 | baseObject=None
131 | ):
132 |
133 | """
134 | :param prefix:str, prefix to name new objects
135 | :param baseObject:instance of base.module.Base() class
136 | :return None
137 | """
138 | self.topGrp = cmds.group(n=prefix + rigPartName + '_Module_Grp', em=1)
139 |
140 | self.dontTouchGrp = cmds.group(n=prefix + rigPartName + '_Dont_Touch_Grp',
141 | em=1, p=self.topGrp)
142 |
143 | cmds.hide(self.dontTouchGrp)
144 |
145 | cmds.setAttr(self.dontTouchGrp + '.it', 0, l=1)
146 |
147 | Module.addAttr(group=self.topGrp)
148 |
149 | if not cmds.attributeQuery(prefix + rigPartName + '_Jnt', node=self.topGrp, exists=1):
150 | cmds.addAttr(self.topGrp, longName=prefix + rigPartName + '_Jnt', at='message')
151 |
152 | # parent module
153 |
154 | if baseObject:
155 |
156 | cmds.parent(self.topGrp, baseObject.Master_Ctrl.C)
157 |
158 | cmds.select(cl=1)
159 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/singleRotateControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n =prefix,p =[(-7.105427357601002e-15, -0.3358735290035888, 0.7361468691490706), (-0.030221345939771993, -0.43042515285533867, 0.6908148502394227), (-0.072472769789524, -0.5107046042608161, 0.6274377144647979), (-0.12400997464880703, -0.5684975545498503, 0.5501319071758723), (-0.12400997464880703, -0.5684975545498503, 0.5501319071758723), (-0.12400997464880703, -0.5684975545498503, 0.5501319071758723), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.08197748359885537, -0.540253001036092, 0.5946770761304137), (-0.04551343522386375, -0.48527382262420815, 0.6467685738089758), (-0.015501246831107096, -0.4192182992656619, 0.6896431286557706), (-0.015501246831107096, -0.4192182992656619, 0.6896431286557706), (-0.015501246831107096, -0.4192182992656619, 0.6896431286557706), (-0.015501246831107096, -0.7077292503941806, 0.43808875481816606), (-0.015501246831107096, -0.80800092168273, -0.016811817720621902), (-0.015501246831107096, -0.6943482219457593, -0.34108941639861884), (-0.015501246831107096, -0.5527220271320061, -0.5148315398676033), (-0.015501246831107096, -0.3348935247151239, -0.6771644412642893), (-0.015501246831107096, -0.1758560186022855, -0.7361468691392242), (-0.015501246831107096, -7.844604263429887e-05, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
7 | List.append(cmds.curve( p =[(3.552713678800501e-15, -0.3358735290035959, 0.7361468691490706), (0.03022134593976844, -0.43042515285534577, 0.6908148502394227), (0.07247276978952044, -0.5107046042608232, 0.6274377144647979), (0.12400997464880348, -0.5684975545498574, 0.5501319071758723), (0.12400997464880348, -0.5684975545498574, 0.5501319071758723), (0.12400997464880348, -0.5684975545498574, 0.5501319071758723), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.08197748359885182, -0.5402530010360991, 0.5946770761304137), (0.0455134352238602, -0.48527382262421526, 0.6467685738089758), (0.015501246831103543, -0.419218299265669, 0.6896431286557706), (0.015501246831103543, -0.419218299265669, 0.6896431286557706), (0.015501246831103543, -0.419218299265669, 0.6896431286557706), (0.015501246831103543, -0.7077292503941877, 0.43808875481816606), (0.015501246831103543, -0.8080009216827371, -0.016811817720621902), (0.015501246831103543, -0.6943482219457664, -0.34108941639861884), (0.015501246831103543, -0.5527220271320132, -0.5148315398676033), (0.015501246831103543, -0.334893524715131, -0.6771644412642893), (0.015501246831103543, -0.1758560186022926, -0.7361468691392242), (0.015501246831103543, -7.844604263433487e-05, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
8 | List.append(cmds.curve( p =[(0.0, 0.33587352900359235, 0.7361468691490706), (-0.030221345939764888, 0.4304251528553422, 0.6908148502394227), (-0.07247276978951689, 0.5107046042608197, 0.6274377144647979), (-0.12400997464879993, 0.5684975545498538, 0.5501319071758723), (-0.12400997464879993, 0.5684975545498538, 0.5501319071758723), (-0.12400997464879993, 0.5684975545498538, 0.5501319071758723), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.08197748359884827, 0.5402530010360955, 0.5946770761304137), (-0.045513435223856646, 0.4852738226242117, 0.6467685738089758), (-0.01550124683109999, 0.41921829926566545, 0.6896431286557706), (-0.01550124683109999, 0.41921829926566545, 0.6896431286557706), (-0.01550124683109999, 0.41921829926566545, 0.6896431286557706), (-0.01550124683109999, 0.7077292503941841, 0.43808875481816606), (-0.01550124683109999, 0.8080009216827335, -0.016811817720621902), (-0.01550124683109999, 0.6943482219457628, -0.34108941639861884), (-0.01550124683109999, 0.5527220271320097, -0.5148315398676033), (-0.01550124683109999, 0.33489352471512746, -0.6771644412642893), (-0.01550124683109999, 0.17585601860228905, -0.7361468691392242), (-0.01550124683109999, 7.844604263078215e-05, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
9 | List.append(cmds.curve( p =[(3.552713678800501e-15, 0.33587352900359235, 0.7361468691490706), (0.03022134593976844, 0.4304251528553422, 0.6908148502394227), (0.07247276978952044, 0.5107046042608197, 0.6274377144647979), (0.12400997464880348, 0.5684975545498538, 0.5501319071758723), (0.12400997464880348, 0.5684975545498538, 0.5501319071758723), (0.12400997464880348, 0.5684975545498538, 0.5501319071758723), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.08197748359885182, 0.5402530010360955, 0.5946770761304137), (0.0455134352238602, 0.4852738226242117, 0.6467685738089758), (0.015501246831103543, 0.41921829926566545, 0.6896431286557706), (0.015501246831103543, 0.41921829926566545, 0.6896431286557706), (0.015501246831103543, 0.41921829926566545, 0.6896431286557706), (0.015501246831103543, 0.7077292503941841, 0.43808875481816606), (0.015501246831103543, 0.8080009216827335, -0.016811817720621902), (0.015501246831103543, 0.6943482219457628, -0.34108941639861884), (0.015501246831103543, 0.5527220271320097, -0.5148315398676033), (0.015501246831103543, 0.33489352471512746, -0.6771644412642893), (0.015501246831103543, 0.17585601860228905, -0.7361468691392242), (0.015501246831103543, 7.844604263078215e-05, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
10 | for x in range(len(List)-1):
11 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
12 | shapeNode = cmds.listRelatives(List[x+1], shapes=True)
13 | cmds.parent(shapeNode, List[0], add=True, s=True)
14 | cmds.delete(List[x+1])
15 | sel = List[0]
16 | cmds.setAttr(sel + '.s', scale, scale, scale)
17 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
18 | return sel
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/CrownCurve.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='new', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n=prefix, p=[(10.235979856897208, 0.5387466956416631, -5.064001608160172), (10.151485877817008, 0.5387466956416631, -5.062031610699659), (9.56002041972143, -0.5387466956416631, -5.048241451174565), (9.47552644064123, -0.5387466956416631, -5.046271453714052), (8.581458580479284, -0.5387466956416631, -6.782167046977893), (7.226633650695048, -0.5387466956416631, -8.241302021399537), (5.569970571620038, -0.5387466956416631, -9.259395857943009), (5.575918387952802, -0.5387466956416631, -9.334794752747538), (5.617553637591014, 0.5387466956416667, -9.862593802347586), (5.623501453923778, 0.5387466956416667, -9.937992697152108), (5.0018396866720405, 0.5387466956416667, -10.290595824653057), (4.344093509091591, 0.5387466956416667, -10.585980197725444), (3.656702513277194, 0.5387466956416667, -10.818273589216776), (3.6060751545400915, 0.5387466956416667, -10.765222345604261), (3.251679086872498, -0.5387466956416631, -10.393858865656984), (3.201051728135395, -0.5387466956416631, -10.34080762204447), (2.1905747659419728, -0.5387466956416631, -10.658773119819454), (1.115474936823345, -0.5387466956416631, -10.830869090935291), (-7.092061794722326e-06, -0.5387466956416631, -10.830869090935291), (-0.9057626700346137, -0.5387466956416631, -10.830869090935291), (-1.7847953592262602, -0.5387466956416631, -10.717013131144075), (-2.6244812896710616, -0.5387466956416631, -10.504322198408392), (-2.671915676524174, -0.5387466956416631, -10.559882430786612), (-3.0039606536334578, 0.5387466956416667, -10.948809057905049), (-3.05139504048657, 0.5387466956416667, -11.004369290283268), (-3.7515233792550635, 0.5387466956416667, -10.810585794248926), (-4.424716067389001, 0.5387466956416667, -10.552803532725871), (-5.063966147851277, 0.5387466956416667, -10.23594439658832), (-5.062219942102283, 0.5387466956416667, -10.160900101326686), (-5.049996344699226, -0.5387466956416631, -9.635583280441136), (-5.048250138950232, -0.5387466956416631, -9.560538985179509), (-6.768344618571698, -0.5387466956416631, -8.633166802905958), (-8.202614824398106, -0.5387466956416631, -7.245987887288454), (-9.19059576663028, -0.5387466956416631, -5.564601880853754), (-9.273642979575483, -0.5387466956416631, -5.571158032402327), (-9.854980944515814, 0.5387466956416631, -5.617051683301884), (-9.938028157461018, 0.5387466956416631, -5.623607834850457), (-10.290560364344165, 0.5387466956416631, -5.001875146980954), (-10.58594473741656, 0.5387466956416631, -4.344128969400483), (-10.818238128907884, 0.5387466956416631, -3.6568088942038735), (-10.754304619323518, 0.5387466956416631, -3.5957862528671605), (-10.306764298159566, -0.5387466956416631, -3.168622271417508), (-10.242830788575203, -0.5387466956416631, -3.107599630080795), (-10.508995867120388, -0.5387466956416631, -2.1760005789872743), (-10.654581711308394, -0.5387466956416631, -1.1934237878302874), (-10.654581711308394, -0.5387466956416631, -0.17636539230646164), (-10.654581711308394, -0.5387466956416631, 0.7370779806342078), (-10.539193866173035, -0.5387466956416631, 1.6235857029403284), (-10.32297108667168, -0.5387466956416631, 2.469654488985743), (-10.39867730108004, -0.5387466956416631, 2.534286165670114), (-10.92862761556602, 0.5387466956416631, 2.9867137193697637), (-11.004333829974383, 0.5387466956416631, 3.0513453960541277), (-10.810621254557828, 0.5387466956416631, 3.7514879189461716), (-10.55276807241698, 0.5387466956416631, 4.424680607080102), (-10.235979856897215, 0.5387466956416631, 5.063930687542385), (-10.130684280632012, 0.5387466956416631, 5.061475282707608), (-9.393605770078961, -0.5387466956416667, 5.044287227875511), (-9.288310193813759, -0.5387466956416667, 5.041831823040734), (-8.391901953264908, -0.5387466956416667, 6.633886219314075), (-7.1000970844439895, -0.5387466956416667, 7.973335559162624), (-5.543446260568659, -0.5387466956416667, 8.923629285104123), (-5.552341193102345, -0.5387466956416667, 9.03633520381678), (-5.614606521390096, 0.5387466956416596, 9.825286778439466), (-5.623501453923781, 0.5387466956416596, 9.937992697152122), (-5.001839686672065, 0.5387466956416596, 10.290581640529492), (-4.344164429709375, 0.5387466956416596, 10.585980197725451), (-3.6568443545127725, 0.5387466956416596, 10.818202668598989), (-3.5769207695409566, 0.5387466956416596, 10.734477776527367), (-3.017448481543612, -0.5387466956416667, 10.148395996710402), (-2.937524896571796, -0.5387466956416667, 10.06467110463878), (-2.0040677252923462, -0.5387466956416667, 10.331999281315642), (-1.0193491314782452, -0.5387466956416667, 10.47813830632236), (-7.092061794722326e-06, -0.5387466956416667, 10.47813830632236), (0.8160055361665552, -0.5387466956416667, 10.47813830632236), (1.609493776186552, -0.5387466956416667, 10.383317440344502), (2.372925858389463, -0.5387466956416667, 10.209618663266713), (2.4483089932143027, -0.5387466956416667, 10.297923405434528), (2.9759977215381763, 0.5387466956416596, 10.916064548115461), (3.051380856363016, 0.5387466956416596, 11.004369290283268), (3.7515233792550386, 0.5387466956416596, 10.810571610125375), (4.424716067388983, 0.5387466956416596, 10.552803532725864), (5.063895227233479, 0.5387466956416596, 10.23594439658832), (5.061247550646554, 0.5387466956416596, 10.122168375255118), (5.042713576244813, -0.5387466956416667, 9.325725985978384), (5.040065899657895, -0.5387466956416667, 9.211949964645182), (6.647495885866908, -0.5387466956416667, 8.347200687875347), (8.005370402215865, -0.5387466956416667, 7.080728663727033), (8.983918902282715, -0.5387466956416667, 5.548190849898429), (9.089929981625572, -0.5387466956416667, 5.556554671116768), (9.832017078118147, 0.5387466956416631, 5.615102172396551), (9.93802815746101, 0.5387466956416631, 5.623465993614889), (10.290546180220593, 0.5387466956416631, 5.001804226363166), (10.586015658034347, 0.5387466956416631, 4.3440580487826885), (10.81823812890787, 0.5387466956416631, 3.656737973586086), (10.74537028684061, 0.5387466956416631, 3.587187607242317), (10.235288834198405, -0.5387466956416631, 3.1003287832403963), (10.162420992131137, -0.5387466956416631, 3.030778416896627), (10.481563772161335, -0.5387466956416631, 2.018500071011484), (10.654581711308394, -0.5387466956416631, 0.9413860963477667), (10.654581711308394, -0.5387466956416631, -0.17636539230646164), (10.654581711308394, -0.5387466956416631, -0.9846902255669683), (10.561491308404454, -0.5387466956416631, -1.7709020102022812), (10.390983959126983, -0.5387466956416631, -2.5277668431983464), (10.459133263276838, -0.5387466956416631, -2.5859432322041194), (10.936184525824528, 0.5387466956416631, -2.993183191171905), (11.004333829974383, 0.5387466956416631, -3.051359580177678), (10.810621254557814, 0.5387466956416631, -3.751558839563952), (10.552768072416965, 0.5387466956416631, -4.4247515276978895), (10.235979856897208, 0.5387466956416631, -5.064001608160172)],
7 | per=False,
8 | d=3,k=[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36]))
9 | for x in range(len(List)-1):
10 | cmds.makeIdentity(List[x+1], apply=True, t=1, r=1, s=1, n=0)
11 | shapeNode = cmds.ListRelatives(List[x+1], shapes=True)
12 | cmds.parent(shapeNode, List[0], add=True, s=True)
13 | cmds.delete(List[x+1])
14 |
15 | sel = List[0]
16 | cmds.setAttr(sel + '.s', scale, scale, scale)
17 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
18 | return sel
19 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/Blend_RollChain.py:
--------------------------------------------------------------------------------
1 | from maya import cmds
2 |
3 |
4 | def build(rollStart,
5 | rollEnd,
6 | numRollJoints=1,
7 | rollWithSameDir=True
8 | ):
9 | """
10 | create a single bone roll joints chain with desired roll joints, blend rotation between rollStart and rollEnd joints
11 | :param rollStart: str, create roll joints from rollStart joint
12 | :param rollEnd: str, create roll joints ends at rollEnd joint
13 | :param roll_Parent: str, parent ik_roll_joints to roll_Parent joint.
14 | If rollWithSameDir is True, roll_Parent is the joint above rollStart joint by 1 step
15 | example: upper arm: Clavical; hip: body_pivot or c_spine_0
16 | If rollWithSameDir is False, roll_Parent is the rollStart joint
17 | example: lower arm: Elbow
18 | :param IK_Parent: str, parent ik handle to the IK_Parent joints
19 | If rollWithSameDir is True, IK_Parent is the joint above rollStart joint by 1 step
20 | example: upper arm: Clavical; hip: body_pivot or c_spine_0
21 | If rollWithSameDir is False, IK_Parent is the rollStart joint
22 | example: lower arm: Wrist
23 | :param numRollJoints: int, number of roll joints between rollStart joint and rollEnd joint
24 | :param rollWithSameDir: bool, whether the roll joints are the same generation direction
25 | with the original joints chain direction
26 | :return: None
27 | """
28 | if numRollJoints < 1:
29 | raise RuntimeError('Param: numRollJoints must larger than 1, please input correct int number again!')
30 | return
31 |
32 | if rollWithSameDir:
33 | roll_Parent = cmds.listRelatives(rollStart, p=1, c=0, s=0, type='joint')[0]
34 | IK_Parent = cmds.listRelatives(rollStart, p=1, c=0, s=0, type='joint')[0]
35 | else:
36 | roll_Parent = rollStart
37 | IK_Parent = rollStart
38 |
39 | rollJointList = []
40 |
41 | # create the start and end roll joints
42 | rollStart_Jnt = cmds.joint(n=rollStart + '_Roll_Start')
43 | cmds.select(cl=1)
44 | rollEnd_Jnt = cmds.joint(n=rollStart + '_Roll_End')
45 | cmds.select(cl=1)
46 |
47 | # transform the joint
48 | pc1 = cmds.parentConstraint(rollStart, rollStart_Jnt, mo=0)
49 | cmds.delete(pc1)
50 | pc2 = cmds.parentConstraint(rollEnd, rollEnd_Jnt, mo=0)
51 | cmds.delete(pc2)
52 |
53 | # freeze transformation
54 | cmds.makeIdentity(rollStart_Jnt, apply=1, t=1, r=1, s=1)
55 | cmds.makeIdentity(rollEnd_Jnt, apply=1, t=1, r=1, s=1)
56 |
57 | # parent and get the .tx attribute
58 | cmds.parent(rollEnd_Jnt, rollStart_Jnt)
59 | totalLength = cmds.getAttr(rollEnd_Jnt + '.tx')
60 |
61 | eachLeagth = totalLength / (numRollJoints + 1)
62 |
63 | # create IK Handle
64 | ikHandle = cmds.ikHandle(n=rollStart + '_Roll_IK', sj=rollStart_Jnt, ee=rollEnd_Jnt, s='sticky', sol='ikSCsolver')
65 | cmds.parent(ikHandle[0], IK_Parent)
66 | cmds.pointConstraint(rollEnd, ikHandle[0], mo=0)
67 |
68 | rollJointList.append(rollStart_Jnt)
69 |
70 | if rollWithSameDir:
71 | rollDir = rollStart
72 | rollOrient = rollStart
73 | # create middle roll joints and transform it
74 | for i in range(0, numRollJoints):
75 | middleRoll_Jnt = cmds.duplicate(rollEnd_Jnt, n=rollStart + '_Roll_' + str(i + 1))
76 | cmds.setAttr(middleRoll_Jnt[0] + '.tx', eachLeagth * (int(i) + 1))
77 | cmds.parent(middleRoll_Jnt, rollDir)
78 |
79 | oc = cmds.orientConstraint(rollOrient, rollStart_Jnt, middleRoll_Jnt, mo=0)
80 | cmds.setAttr(oc[0] + '.' + rollStart_Jnt + 'W1', (len(range(0, numRollJoints)) - int(i)))
81 | cmds.setAttr(oc[0] + '.' + rollOrient + 'W0', (int(i) + 1))
82 |
83 | rollJointList.append(middleRoll_Jnt[0])
84 |
85 | else:
86 | rollDir = rollEnd
87 | rollOrient = rollEnd
88 | # create middle roll joints and transform it
89 | for i in range(0, numRollJoints):
90 | middleRoll_Jnt = cmds.duplicate(rollEnd_Jnt, n=rollStart + '_Roll_' + str(i + 1))
91 | cmds.setAttr(middleRoll_Jnt[0] + '.tx', eachLeagth * (int(i) + 1))
92 | cmds.parent(middleRoll_Jnt, rollDir)
93 |
94 | oc = cmds.orientConstraint(rollOrient, rollStart, middleRoll_Jnt, mo=0)
95 | cmds.setAttr(oc[0] + '.' + rollStart + 'W1', (len(range(0, numRollJoints)) - int(i)))
96 | cmds.setAttr(oc[0] + '.' + rollOrient + 'W0', (int(i) + 1))
97 |
98 | rollJointList.append(middleRoll_Jnt[0])
99 |
100 | # parent
101 | cmds.parent(rollStart_Jnt, roll_Parent)
102 |
103 | #############
104 | # attribute #
105 | #############
106 | if rollWithSameDir:
107 | # slave pointConstraint attr
108 | if not cmds.attributeQuery('slavePointConst', node=rollStart, exists=1):
109 | cmds.addAttr(rollStart, ln='slavePointConst', dt='string')
110 |
111 | cmds.setAttr(rollStart + '.slavePointConst', cmds.ls(rollEnd, long=1)[0], type='string', lock=1)
112 |
113 | if not cmds.attributeQuery('slaveParent', node=rollStart, exists=1):
114 | cmds.addAttr(rollStart, ln='slaveParent', dt='string')
115 |
116 | cmds.setAttr(rollStart + '.slaveParent', cmds.ls(rollJointList[-1], long=1)[0], type='string', lock=1)
117 |
118 | # slave parent attr
119 | for i in xrange(len(rollJointList) - 1):
120 | if not cmds.attributeQuery('slaveParent', node=rollJointList[i + 1], exists=1):
121 | cmds.addAttr(rollJointList[i + 1], ln='slaveParent', dt='string')
122 | cmds.setAttr(rollJointList[i + 1] + '.slaveParent', cmds.ls(rollJointList[i], long=1)[0], type='string',
123 | lock=1)
124 | else:
125 | # add and set attr
126 | if not cmds.attributeQuery('slaveParent', node=rollStart, exists=1):
127 | cmds.addAttr(rollStart, ln='slaveParent', dt='string')
128 | cmds.setAttr(rollStart + '.slaveParent', cmds.ls(rollStart_Jnt, long=1)[0], type='string', lock=1)
129 |
130 | for i in xrange(len(rollJointList) - 1):
131 | if not cmds.attributeQuery('slaveParent', node=rollJointList[i], exists=1):
132 | cmds.addAttr(rollJointList[i], ln='slaveParent', dt='string')
133 | cmds.setAttr(rollJointList[i] + '.slaveParent', cmds.ls(rollJointList[i+1], long=1)[0], type='string',
134 | lock=1)
135 |
136 | # add attr
137 | for joint in rollJointList:
138 | if not cmds.attributeQuery('rigModule', node=joint, exists=1):
139 | cmds.addAttr(joint, ln='rigModule', at='message')
140 |
141 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
142 | cmds.addAttr(joint, ln='slaveJoint', at='message')
143 |
144 | if not cmds.attributeQuery('rollJoint', node=joint, exists=1):
145 | cmds.addAttr(joint, ln='rollJoint', at='bool')
146 | cmds.setAttr(joint + '.rollJoint', 1, lock=1)
147 |
148 | rigModule = cmds.listConnections(rollStart + '.rigModule', source=1, destination=0, shapes=0)[0]
149 |
150 | if not cmds.attributeQuery('rollJoint', node=rigModule, exists=1):
151 | cmds.addAttr(rigModule, ln='rollJoint', at='message')
152 |
153 | for joint in rollJointList:
154 | cmds.connectAttr(rigModule + '.rollJoint', joint + '.rigModule', f=1)
155 |
156 | cmds.select(cl=1)
157 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/Edit_UI.py:
--------------------------------------------------------------------------------
1 | from PySide2 import QtWidgets
2 | import maya.cmds as cmds
3 | import logging
4 | import inspect
5 | from functools import partial
6 | import Splitter_UI
7 |
8 |
9 | class EditWidget(QtWidgets.QDialog):
10 | def __init__(self, instance, uiName, functionName):
11 |
12 | logging.basicConfig()
13 | logger = logging.getLogger('%s' % uiName)
14 | logger.setLevel(logging.INFO)
15 |
16 | try:
17 | cmds.deleteUI('%s' % uiName)
18 | except:
19 | logger.info('No %s exists!' % uiName)
20 |
21 | super(EditWidget, self).__init__(parent=instance)
22 | self.setObjectName('%s' % uiName)
23 | self.setWindowTitle('%s' % uiName)
24 | self.setModal(False)
25 |
26 | self.instance = instance
27 | self.functionName = functionName
28 |
29 | # Turn on track selection order for selecting vertices and lines 1 by 1
30 | self.TSO_Type = cmds.selectPref(q=1, tso=1)
31 | cmds.selectPref(tso=1)
32 |
33 | self.buildUI()
34 | self.populate()
35 | self.show()
36 | self.refreshListWidget()
37 |
38 | def buildUI(self):
39 | """
40 | Build the Edit UI
41 | :return: None
42 | """
43 | # Main layout
44 | self.mainLayout = QtWidgets.QGridLayout()
45 | self.setLayout(self.mainLayout)
46 |
47 | # parameters part
48 | self.paramSplitterWidget = Splitter_UI.Splitter('Parameters')
49 |
50 | self.formWidget = QtWidgets.QFrame()
51 | self.formWidget.setFrameStyle(QtWidgets.QFrame.StyledPanel)
52 | self.formWidget.setFrameShadow(QtWidgets.QFrame.Plain)
53 | self.formLayout = QtWidgets.QFormLayout()
54 | self.formWidget.setLayout(self.formLayout)
55 |
56 | # Selection part
57 | self.selSplitterWidget = Splitter_UI.Splitter('Check & Select')
58 |
59 | selectionWidget = QtWidgets.QFrame()
60 | selectionWidget.setFrameStyle(QtWidgets.QFrame.StyledPanel)
61 | selectionWidget.setFrameShadow(QtWidgets.QFrame.Plain)
62 |
63 | selectionLayout = QtWidgets.QVBoxLayout()
64 | selectionWidget.setLayout(selectionLayout)
65 |
66 | # filter part
67 | filterWidget = QtWidgets.QWidget()
68 | filterLayout = QtWidgets.QHBoxLayout()
69 | filterWidget.setLayout(filterLayout)
70 | filterLabel = QtWidgets.QLabel('Filter: ')
71 | self.jointCheck = QtWidgets.QCheckBox('joint')
72 | self.locatorCheck = QtWidgets.QCheckBox('locator')
73 |
74 | filterLayout.addWidget(filterLabel)
75 | filterLayout.addWidget(self.jointCheck)
76 | filterLayout.addWidget(self.locatorCheck)
77 |
78 | self.jointCheck.stateChanged.connect(self.refreshListWidget)
79 | self.locatorCheck.stateChanged.connect(self.refreshListWidget)
80 |
81 | # arrangement
82 | self.mainLayout.addWidget(self.paramSplitterWidget, 0, 0, 1, 1)
83 | self.mainLayout.addWidget(self.formWidget, 1, 0, 1, 1)
84 | self.mainLayout.addWidget(self.selSplitterWidget, 0, 1, 1, 1)
85 | self.mainLayout.addWidget(selectionWidget, 1, 1, 1, 1)
86 |
87 | self.listWidget = QtWidgets.QListWidget()
88 | self.listWidget.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
89 |
90 | self.rowItem = {}
91 | self.tupe = inspect.getargspec(func=self.functionName)
92 | for i in self.tupe[0]:
93 | layout = QtWidgets.QHBoxLayout()
94 |
95 | self.rowItem[i] = QtWidgets.QLineEdit()
96 | button = QtWidgets.QPushButton('<<<')
97 |
98 | layout.addWidget(self.rowItem[i])
99 | layout.addWidget(button)
100 |
101 | button.clicked.connect(partial(self.setEditLine, self.rowItem[i]))
102 |
103 | self.formLayout.addRow(i, layout)
104 |
105 | selectionLayout.addWidget(filterWidget)
106 | selectionLayout.addWidget(self.listWidget)
107 |
108 | # selectionWidget.setMaximumHeight(self.formWidget.height())
109 |
110 | self.createGeneralButton(self.mainLayout)
111 |
112 | def setEditLine(self, editLine):
113 | """
114 | set specified editLine text
115 | :param editLine: specified editLine
116 | :return: None
117 | """
118 | # listWidget selected items
119 | listItems = self.listWidget.selectedItems()
120 | itemStr = []
121 | for i in listItems:
122 | itemStr.append(self.listWidget.item(self.listWidget.row(i)).text())
123 |
124 | # vertices or lines
125 | selList = cmds.ls(os=1)
126 |
127 | finalList = itemStr + selList
128 |
129 | if finalList:
130 | if len(finalList) < 2:
131 | editLine.setText(finalList[0])
132 | else:
133 | editLine.setText(str(finalList))
134 |
135 | def saveData(self):
136 | """
137 | Save the args info to the specified rig widget's rigArgs dictionary
138 | :return: None
139 | """
140 | tupe = inspect.getargspec(self.functionName)
141 | for i in tupe[0]:
142 | self.instance.rigArgs[i] = self.rowItem[i].text()
143 |
144 | def setData(self):
145 | """
146 | Save the rigArgs info and close the rigArgs dialog
147 | :return: None
148 | """
149 | self.saveData()
150 |
151 | self.close()
152 |
153 | cmds.selectPref(tso=self.TSO_Type)
154 |
155 | def cancel(self):
156 | """
157 | Cancel button action -> close the rigArgs dialog
158 | :return: None
159 | """
160 | self.close()
161 | cmds.selectPref(tso=self.TSO_Type)
162 |
163 | def populate(self):
164 | """
165 | Refresh and populate the rigArgs info for each arg
166 | :return: None
167 | """
168 | for arg in self.instance.rigArgs.keys():
169 | if arg in self.rowItem.keys():
170 | self.rowItem[arg].setText(str(self.instance.rigArgs[arg]))
171 | else:
172 | raise RuntimeWarning('No specified properties!')
173 |
174 | def createGeneralButton(self, layout):
175 | """
176 | Create the Cancel and OK button for each widget
177 | :param layout: the edit window main widget
178 | :return: None
179 | """
180 | btnWidget = QtWidgets.QWidget()
181 | btnLayout = QtWidgets.QHBoxLayout(btnWidget)
182 | layout.addWidget(btnWidget, 2, 0, 1, 2)
183 |
184 | cancel_Btn = QtWidgets.QPushButton('Cancel')
185 | OK_Btn = QtWidgets.QPushButton('OK')
186 |
187 | btnLayout.addWidget(cancel_Btn)
188 | btnLayout.addWidget(OK_Btn)
189 |
190 | OK_Btn.clicked.connect(self.setData)
191 | cancel_Btn.clicked.connect(self.cancel)
192 |
193 | def refreshListWidget(self):
194 | """
195 | refresh listWidget with specified checked
196 | :return: None
197 | """
198 |
199 | self.listWidget.clear()
200 |
201 | joints = []
202 | locators = []
203 | if self.jointCheck.isChecked():
204 | joints = cmds.ls(type='joint')
205 |
206 | locaterShapes = []
207 | if self.locatorCheck.isChecked():
208 | locaterShapes = cmds.ls(type='locator')
209 |
210 | for loc in locaterShapes:
211 | locators.append(cmds.listRelatives(loc, p=1)[0])
212 |
213 | returnList = joints + locators
214 |
215 | if returnList:
216 | if len(returnList) > 1:
217 | self.listWidget.addItems(returnList)
218 | else:
219 | self.listWidget.addItem(returnList[0])
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/control.py:
--------------------------------------------------------------------------------
1 | """
2 | module for making rig control
3 | """
4 |
5 | import maya.cmds as cmds
6 | import controlShape
7 | reload(controlShape)
8 |
9 |
10 | class Control():
11 |
12 | """
13 | class for building rig control
14 | """
15 |
16 | def __init__(self,
17 | prefix='L_',
18 | rigPartName='',
19 | scale=1.0,
20 | translateTo='',
21 | rotateTo='',
22 | parent='',
23 | shape='circle',
24 | axis='x',
25 | lockChannels=['s', 'v']):
26 | """
27 | create rig control and rig offset group
28 | :param prefix: str, prefix to name new objects
29 | :param rigPartName: str, rig part name
30 | :param scale: float, scale value for size of control shapes
31 | :param translateTo: str, reference object for control position
32 | :param rotateTo: str,reference object for control orientation
33 | :param parent:str, object to be parent of new control
34 | :param shape: str, control shape type
35 | :param lockChannels: list(str), list of channels on control to be locked and non-keyable
36 | """
37 |
38 | circleNormal = [1, 0, 0]
39 | ctrlObject = None
40 |
41 | if shape in ['circle', 'circleX']:
42 |
43 | circleNormal = [1, 0, 0]
44 |
45 | elif shape == 'circleY':
46 |
47 | circleNormal = [0, 1, 0]
48 |
49 | elif shape == 'circleZ':
50 |
51 | circleNormal = [0, 0, 1]
52 |
53 | elif shape == 'sphere':
54 | ctrlObject = cmds.circle(n=prefix + rigPartName + '_Ctrl', ch=False, normal=[1, 0, 0], radius=scale)[0]
55 | addShape = cmds.circle(n=prefix + rigPartName + '_Ctrl2', ch=False, normal=[0, 0, 1], radius=scale)[0]
56 | cmds.parent(cmds.listRelatives(addShape, s=1), ctrlObject, r=1, s=1)
57 | cmds.delete(addShape)
58 |
59 | elif shape == 'crossControl':
60 | ctrlObject = controlShape.CrossControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
61 |
62 | elif shape == 'arrowCurve':
63 | ctrlObject = controlShape.ArrowCurve.createShape(prefix=prefix + rigPartName + '_Ctrl')
64 |
65 | elif shape == 'crownCurve':
66 | ctrlObject = controlShape.CrownCurve.createShape(prefix=prefix + rigPartName + '_Ctrl')
67 |
68 | elif shape == 'cubeCurve':
69 | ctrlObject = controlShape.CubeCurve.createShape(prefix=prefix + rigPartName + '_Ctrl')
70 |
71 | elif shape == 'cubeOnBase':
72 | ctrlObject = controlShape.cubeOnBase.createShape(prefix=prefix + rigPartName + '_Ctrl')
73 |
74 | elif shape == 'diamond':
75 | ctrlObject = controlShape.Diamond.createShape(prefix=prefix + rigPartName + '_Ctrl')
76 |
77 | elif shape == 'fistCurve':
78 | ctrlObject = controlShape.FistCurve.createShape(prefix=prefix + rigPartName + '_Ctrl')
79 |
80 | elif shape == 'footControl':
81 | ctrlObject = controlShape.FootControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
82 |
83 | elif shape == 'moveControl':
84 | ctrlObject = controlShape.MoveControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
85 |
86 | elif shape == 'rotationControl':
87 | ctrlObject = controlShape.RotationControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
88 |
89 | elif shape == 'singleRotateControl':
90 | ctrlObject = controlShape.singleRotateControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
91 |
92 | elif shape == 'spikeCrossControl':
93 | ctrlObject = controlShape.SpikeCrossControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
94 |
95 | elif shape == 'unitSliderControl':
96 | ctrlBox = controlShape.unitSliderControl.createShape(prefix=prefix + rigPartName)
97 | ctrlObject = cmds.listRelatives(ctrlBox, children=1, parent=0, s=0)
98 | ctrlObject = ctrlObject[1]
99 |
100 | elif shape == 'squareControl':
101 | ctrlObject = controlShape.squareControl.createShape(prefix=prefix + rigPartName + '_Ctrl')
102 |
103 | if not ctrlObject:
104 | ctrlObject = cmds.circle(n=prefix + rigPartName + '_Ctrl', ch=1,
105 | normal=circleNormal, radius=1.0)[0]
106 |
107 | # rotate the ctrlObject
108 | if shape in ['circle', 'circleX', 'circleY', 'circleZ']:
109 | pass
110 | else:
111 | self.rotate_Ctrl(ctrlObject=ctrlObject, shape=shape, axis=axis)
112 |
113 | # ctrl offset group
114 | ctrlOffset = cmds.group(n=prefix + rigPartName + '_CtrlGrp', em=1)
115 | if shape in ['unitSliderControl']:
116 | cmds.parent(ctrlBox, ctrlOffset)
117 | else:
118 | cmds.parent(ctrlObject, ctrlOffset)
119 |
120 | # scale the control grp
121 | cmds.setAttr(ctrlOffset + '.s', scale, scale, scale)
122 |
123 | # color control
124 | ctrlShapes = cmds.listRelatives(ctrlObject, s=1)
125 |
126 | [cmds.setAttr(s + '.ove', 1) for s in ctrlShapes]
127 |
128 | if prefix.startswith('L_'):
129 | [cmds.setAttr(s + '.ovc', 6) for s in ctrlShapes]
130 |
131 | elif prefix.startswith('R_'):
132 | [cmds.setAttr(s + '.ovc', 13) for s in ctrlShapes]
133 |
134 | else:
135 | [cmds.setAttr(s + '.ovc', 22) for s in ctrlShapes]
136 |
137 | # translate control
138 |
139 | if cmds.objExists(translateTo):
140 | cmds.delete(cmds.pointConstraint(translateTo, ctrlOffset, mo=0))
141 |
142 | # rotate control
143 |
144 | if cmds.objExists(rotateTo):
145 | cmds.delete(cmds.orientConstraint(rotateTo, ctrlOffset, mo=0))
146 |
147 | # parent control
148 |
149 | if cmds.objExists(parent):
150 | cmds.parent(ctrlOffset, parent)
151 |
152 | # lock control channels
153 |
154 | singleAttributeLockList = []
155 | for lockChannel in lockChannels:
156 |
157 | if lockChannel in ['t', 'r', 's']:
158 |
159 | for axis in ['x', 'y', 'z']:
160 |
161 | at = lockChannel + axis
162 | singleAttributeLockList.append(at)
163 |
164 | else:
165 | singleAttributeLockList.append(lockChannel)
166 |
167 | for at in singleAttributeLockList:
168 | cmds.setAttr(ctrlObject + '.' + at, l=1, k=0)
169 |
170 | # add public members
171 |
172 | self.C = ctrlObject
173 | self.Off = ctrlOffset
174 |
175 | def rotate_Ctrl(self, ctrlObject, shape, axis='x'):
176 | """
177 | not support for sliderControl and unitSliderControl
178 | :param ctrlObject: INSTANCE.C
179 | :param shape: control shape
180 | :param axis: forward axis
181 | :return: None
182 | """
183 | ctrlShape = cmds.listRelatives(ctrlObject, s=1, type='nurbsCurve')
184 |
185 | cls = cmds.cluster(ctrlShape)[1]
186 |
187 | if axis == 'x' and shape in ['crossControl', 'crownCurve', 'fistCurve',
188 | 'footControl', 'moveControl', 'spikeCrossControl']:
189 | cmds.setAttr(cls + '.rz', 90)
190 |
191 | elif axis == 'x' and shape in ['rotationControl', 'singleRotateControl']:
192 | cmds.setAttr(cls + '.ry', 90)
193 |
194 | elif axis == 'z' and shape in ['arrowCurve', 'crossControl', 'crownCurve', 'cubeOnBase', 'fistCurve',
195 | 'footControl', 'moveControl', 'spikeCrossControl']:
196 | cmds.setAttr(cls + '.rx', 90)
197 |
198 | elif axis == 'y' and shape in ['rotationControl', 'singleRotateControl']:
199 | cmds.setAttr(cls + '.rx', 90)
200 |
201 | elif axis == 'y' and shape in ['squareControl']:
202 | cmds.setAttr(cls + '.rz', 90)
203 |
204 | elif axis == 'z' and shape in ['squareControl']:
205 | cmds.setAttr(cls + '.ry', 90)
206 |
207 | elif axis == 'x' and shape in ['cubeOnBase']:
208 | cmds.move(0, 0, 0, [cls + '.scalePivot', cls + '.rotatePivot'], rpr=1)
209 | cmds.setAttr(cls + '.rz', -90)
210 | elif axis == 'x' and shape in ['arrowCurve']:
211 | cmds.move(0, 0, 0, [cls + '.scalePivot', cls + '.rotatePivot'], rpr=1)
212 | cmds.setAttr(cls + '.ry', -90)
213 | cmds.setAttr(cls + '.rx', -90)
214 | else:
215 | pass
216 |
217 | # delete the cluster
218 | cmds.delete(ctrlShape, ch=1)
219 |
220 | cmds.select(cl=1)
221 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/IK_AnimalLeg.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | from ..base import module
4 | from ..base import control
5 |
6 | from ..utils import name
7 |
8 | reload(module)
9 | reload(control)
10 | reload(name)
11 |
12 |
13 | def build(legJoints,
14 | revJntlocList,
15 | ankleRollLoc,
16 | spineJnt='',
17 | prefix='L_',
18 | rigScale=1.0,
19 | baseRig=None):
20 | """
21 | IK animal leg rig, for
22 | :param legJoints: list(str), leg joints.[hip, knee, ankle, ball, toe, toeEnd]
23 | :param revJntlocList: list(str), rev_joint locator list.[CBank, EBank, Heel, Pivot]
24 | :param ankleRollLoc: str, ankleRoll locator.
25 | :param spineJnt: str, start joint of the spine(i.e. spine_0)
26 | :param prefix: str, 'L_' OR 'L_Front'...
27 | :param rigScale: float, rig scale of the module.
28 | :param baseRig: instance, base attach of the rig. Base Class instance is used.
29 | :return: None.
30 | """
31 | rigPartName = 'AnimLeg'
32 |
33 | if spineJnt:
34 | try:
35 | cmds.objectType(spineJnt) == 'joint'
36 | except:
37 | cmds.error('%s is not a joint type!' %spineJnt)
38 | else:
39 | parentJnt = cmds.listRelatives(legJoints[0], s=0, children=0, parent=1, type='joint')
40 | if parentJnt:
41 | spineJnt = parentJnt
42 | else:
43 | pass
44 |
45 | cmds.select(cl=1)
46 |
47 | rigModule = module.Module(prefix=prefix,
48 | rigPartName=rigPartName,
49 | baseObject=baseRig)
50 |
51 | hintFirstLength = cmds.getAttr(legJoints[2] + '.tx')
52 | hintSecondLength = cmds.getAttr(legJoints[1] + '.tx') + cmds.getAttr(legJoints[3] + '.tx')
53 |
54 | cmds.select(cl=1)
55 |
56 | # create IK_HintLeg
57 | hintJnt_List = []
58 | for i in xrange(3):
59 | hintJnt = cmds.joint(n=prefix + rigPartName + 'Hint_Jnt' + str(i))
60 | cmds.setAttr(hintJnt + '.drawStyle', 2)
61 | cmds.select(cl=1)
62 | hintJnt_List.append(hintJnt)
63 |
64 | for i in xrange(len(hintJnt_List)-1):
65 | cmds.parent(hintJnt_List[i+1], hintJnt_List[i])
66 |
67 | cmds.setAttr(hintJnt_List[1] + '.tx', hintFirstLength)
68 | cmds.setAttr(hintJnt_List[2] + '.tx', hintSecondLength)
69 |
70 | cmds.select(cl=1)
71 |
72 | cmds.setAttr(hintJnt_List[0] + '.rotateX', -90)
73 | cmds.setAttr(hintJnt_List[0] + '.rotateZ', 90)
74 |
75 | cmds.setAttr(hintJnt_List[1] + '.rotateZ', 90)
76 |
77 | cmds.makeIdentity(hintJnt_List[0], apply=1, t=1, r=1, s=1, n=0, pn=1)
78 |
79 | # hint leg ik
80 | IK_Hint_Part_List = cmds.ikHandle(n=prefix + rigPartName + 'hintLeg_IK', sj=hintJnt_List[0],
81 | ee=hintJnt_List[-1], sol='ikRPsolver')
82 |
83 | pc1 = cmds.pointConstraint(legJoints[0], hintJnt_List[0], mo=0)
84 | cmds.delete(pc1)
85 | pc2 = cmds.pointConstraint(legJoints[3], IK_Hint_Part_List[0], mo=0)
86 | cmds.delete(pc2)
87 |
88 | # create footCtrl and rev joints
89 | Foot_IK_Ctrl = control.Control(prefix=prefix,
90 | rigPartName=rigPartName,
91 | scale=rigScale*5,
92 | translateTo=legJoints[-2],
93 | rotateTo=legJoints[-2],
94 | shape='footControl',
95 | axis='y',
96 | lockChannels=['v'])
97 | cmds.select(cl=1)
98 | # flatten Ctrl and mirror the Ctrl action by plan YZ
99 | cmds.setAttr(Foot_IK_Ctrl.Off + '.rotateX', 90)
100 | cmds.setAttr(Foot_IK_Ctrl.Off + '.rotateY', 0)
101 | cmds.setAttr(Foot_IK_Ctrl.Off + '.rotateZ', cmds.getAttr(Foot_IK_Ctrl.Off + '.rotateZ') + 90)
102 |
103 | if prefix.startswith('R_'):
104 | cmds.setAttr(Foot_IK_Ctrl.Off + '.scaleZ', cmds.getAttr(Foot_IK_Ctrl.Off + '.scaleZ') * (-1))
105 |
106 | cmds.select(cl=1)
107 |
108 | revJntList = []
109 | for i in xrange(len(revJntlocList)):
110 | revJnt = cmds.joint(n=(name.removeSuffix(revJntlocList[i]) + '_Rev'))
111 | cmds.setAttr(revJnt + '.drawStyle', 2)
112 | cmds.select(cl=1)
113 | cmds.delete(cmds.pointConstraint(revJntlocList[i], revJnt, mo=0))
114 | cmds.delete(cmds.orientConstraint(Foot_IK_Ctrl.C, revJnt, mo=0))
115 | revJntList.append(revJnt)
116 |
117 | cmds.select(cl=1)
118 |
119 | for i in revJntlocList:
120 | cmds.delete(i)
121 |
122 | cmds.select(cl=1)
123 |
124 | legJoints_Rev = []
125 | for i in legJoints:
126 | legJoints_Rev.append(i)
127 | legJoints_Rev.reverse()
128 |
129 | cmds.select(cl=1)
130 |
131 | for i in xrange(len(legJoints_Rev[:3])):
132 | revJnt = cmds.joint(n=legJoints_Rev[i] + '_Rev')
133 | cmds.setAttr(revJnt + '.drawStyle', 2)
134 | cmds.select(cl=1)
135 | cmds.delete(cmds.pointConstraint(legJoints_Rev[i], revJnt, mo=0))
136 | cmds.delete(cmds.orientConstraint(Foot_IK_Ctrl.C, revJnt, mo=0))
137 |
138 | revJntList.append(revJnt)
139 |
140 | cmds.select(cl=1)
141 |
142 | # parenting
143 | for i in xrange(len(revJntList)-1):
144 | cmds.parent(revJntList[i+1], revJntList[i])
145 | cmds.select(cl=1)
146 |
147 | cmds.select(cl=1)
148 |
149 | cmds.makeIdentity(revJntList[0], apply=1, t=1, r=1, s=1, n=0, pn=1)
150 |
151 | # create BallRoll_Ctrl and RevJntRoll_Ctrl
152 |
153 | ballRoll_Ctrl = control.Control(prefix=prefix,
154 | rigPartName='BallRoll',
155 | scale=rigScale*3,
156 | translateTo=legJoints[-3],
157 | rotateTo=hintJnt_List[-1],
158 | shape='sphere',
159 | lockChannels=['t', 's', 'v'])
160 | cmds.orientConstraint(hintJnt_List[-1], ballRoll_Ctrl.Off, mo=0)
161 |
162 | cmds.select(cl=1)
163 |
164 | revJntRoll_Ctrl = control.Control(prefix=prefix,
165 | rigPartName='AnkleRoll',
166 | scale=rigScale * 7,
167 | translateTo=ankleRollLoc,
168 | rotateTo=Foot_IK_Ctrl.C,
169 | shape='rotationControl',
170 | axis='y',
171 | lockChannels=['t', 's', 'v'])
172 | cmds.delete(ankleRollLoc)
173 | cmds.select(cl=1)
174 |
175 | # revJntRoll_Ctrl connects attrs to revJntList
176 | cmds.addAttr(revJntRoll_Ctrl.C, ln='Ball2Toe', k=1, at="float", min=0, max=1, dv=0)
177 |
178 | # rotate Z
179 |
180 | condition1 = cmds.createNode('condition', n=prefix + 'Foot_CD#')
181 | cmds.setAttr(condition1 + '.colorIfFalseR', 0)
182 |
183 | cmds.setAttr(condition1 + '.operation', 2)
184 |
185 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateZ', condition1 + '.firstTerm', f=1)
186 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateZ', condition1 + '.colorIfTrueR', f=1)
187 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateZ', condition1 + '.colorIfFalseG', f=1)
188 |
189 | cmds.connectAttr(condition1 + '.outColorR', revJntList[0] + '.rotateZ', f=1)
190 | cmds.connectAttr(condition1 + '.outColorG', revJntList[1] + '.rotateZ', f=1)
191 |
192 | # rotate Y
193 |
194 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateY', revJntList[3] + '.rotateY', f=1)
195 |
196 | # rotate X
197 | condition2 = cmds.createNode('condition', n=prefix + 'Foot_CD#')
198 | cmds.setAttr(condition2 + '.colorIfFalseR', 0)
199 | cmds.setAttr(condition2 + '.operation', 2)
200 |
201 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateX', condition2 + '.firstTerm', f=1)
202 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateX', condition2 + '.colorIfTrueR', f=1)
203 | cmds.connectAttr(revJntRoll_Ctrl.C + '.rotateX', condition2 + '.colorIfFalseG', f=1)
204 |
205 | cmds.connectAttr(condition2 + '.outColorG', revJntList[2] + '.rotateX', f=1)
206 |
207 | blendColors = cmds.createNode('blendColors', n=prefix + 'Foot_BLC#')
208 | cmds.connectAttr(revJntRoll_Ctrl.C + '.Ball2Toe', blendColors + '.blender', f=1)
209 | cmds.connectAttr(condition2 + '.outColorR', blendColors + '.color1R', f=1)
210 | cmds.connectAttr(condition2 + '.outColorR', blendColors + '.color2G', f=1)
211 |
212 | cmds.connectAttr(blendColors + '.outputR', revJntList[4] + '.rotateX', f=1)
213 | cmds.connectAttr(blendColors + '.outputG', revJntList[5] + '.rotateX', f=1)
214 |
215 | cmds.select(cl=1)
216 |
217 | # Create IK for legJoints
218 | IK_Hip_Part_List = cmds.ikHandle(n=prefix + rigPartName + 'Hip_IK', sj=legJoints[0], ee=legJoints[2], sol='ikRPsolver')
219 | IK_Ball_List = cmds.ikHandle(n=prefix + rigPartName + 'Ball_IK', sj=legJoints[2], ee=legJoints[3], sol='ikSCsolver')
220 | IK_Toe_List = cmds.ikHandle(n=prefix + rigPartName + 'Toe_IK', sj=legJoints[3], ee=legJoints[4], sol='ikSCsolver')
221 | IK_ToeEnd_List = cmds.ikHandle(n=prefix + rigPartName + 'ToeEnd_IK', sj=legJoints[-2], ee=legJoints[-1], sol='ikSCsolver')
222 | cmds.select(cl=1)
223 |
224 | # pole vector Ctrl
225 | PV_Ctrl = control.Control(prefix=prefix,
226 | rigPartName='Leg_PV',
227 | scale=rigScale * 18,
228 | translateTo=legJoints[1],
229 | shape='diamond',
230 | lockChannels=['r', 's', 'v'])
231 | cmds.select(cl=1)
232 | cmds.poleVectorConstraint(PV_Ctrl.C, IK_Hint_Part_List[0])
233 | cmds.setAttr(IK_Hint_Part_List[0] + '.twist', 180)
234 | cmds.poleVectorConstraint(PV_Ctrl.C, IK_Hip_Part_List[0])
235 |
236 | cmds.select(cl=1)
237 |
238 | # final parenting
239 | if spineJnt:
240 | cmds.parent(hintJnt_List[0], spineJnt)
241 | else:
242 | cmds.warning('No spine joint, IK system may not work as expected!')
243 | cmds.parent(hintJnt_List[0], rigModule.topGrp)
244 |
245 | cmds.parent(IK_Hip_Part_List[0], ballRoll_Ctrl.C)
246 | cmds.parent(IK_Ball_List[0], ballRoll_Ctrl.C)
247 |
248 | cmds.parent(ballRoll_Ctrl.Off, revJntList[-1])
249 | cmds.parent(IK_Hint_Part_List[0], revJntList[-1])
250 |
251 | cmds.parent(IK_Toe_List[0], revJntList[-2])
252 | cmds.parent(IK_ToeEnd_List[0], revJntList[-3])
253 |
254 | cmds.parent(revJntList[0], Foot_IK_Ctrl.C)
255 | cmds.parent(revJntRoll_Ctrl.Off, Foot_IK_Ctrl.C)
256 |
257 | cmds.parent(PV_Ctrl.Off, rigModule.topGrp)
258 | cmds.parent(Foot_IK_Ctrl.Off, rigModule.topGrp)
259 |
260 | # add Attr
261 | for joint in legJoints:
262 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
263 | cmds.addAttr(joint, longName='slaveJoint', at='message')
264 |
265 | if not cmds.attributeQuery('rigModule', node=joint, exists=1):
266 | cmds.addAttr(joint, longName='rigModule', at='message')
267 |
268 | # connect Attr
269 | for joint in legJoints:
270 | if cmds.attributeQuery('rigModule', node=joint, exists=1):
271 | cmds.connectAttr(rigModule.topGrp + '.' + prefix + rigPartName + '_Jnt',
272 | joint + '.rigModule', f=1)
273 |
274 | cmds.select(cl=1)
275 |
276 | return rigModule
277 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/IK_FK_Spine.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 | from ..base import module
3 | from ..base import control
4 | reload(module)
5 | reload(control)
6 |
7 |
8 | def build(spineJoints,
9 | prefix='C_',
10 | rigScale=1.0,
11 | numFK_Jnt=3,
12 | spineBackUpAxis='y',
13 | mainSpineAttach=None,
14 | baseRig=None):
15 | """
16 | Build IK_FK_Spine rig.
17 | This IK_FK_Spine build module is used for spine joint chain which is placed in the 0 x-Axis position.
18 | :param spineJoints: list(str), original spine joints, from the C_Spine_0 to C_Spine_x, you need to make true that
19 | the spine joints are at same directions, i.e. x-axis is main axis, and z-axis is point to the
20 | -x axis of world space.
21 | :param prefix: str, prefix of the spine, usually, 'C_' is used.
22 | :param rigScale: float, rig scale of the IK_FK_Spine rig module.
23 | :param numFK_Jnt: int, number of FK spine joints, greater than 3.
24 | :param mainSpineAttach: str, main Spine Attach part name, if the spine is not the mainSpine, must set a attachJoint
25 | name to it. Usually the last valid joint of attached part.
26 | :param baseRig: str, base atttach of the rig. Base Class instance is used.
27 | :return: dictionary, rigModule, chest_ctrl (used for upper body parts rig, IK_FK_Arm .etc)and pelvis_ctrl (used for FK_Tail rig)
28 | """
29 | # param check
30 | if numFK_Jnt < 3:
31 | raise RuntimeError('Param: numFK_Jnt must larger than 3!')
32 | return
33 |
34 | # local rigPartName
35 | rigPartName = 'Spine'
36 |
37 | rigModule = module.Module(prefix=prefix,
38 | rigPartName=rigPartName,
39 | baseObject=baseRig)
40 |
41 | if spineBackUpAxis in ['y', 'Y']:
42 | worldUpVector = (0, 1, 0)
43 | elif spineBackUpAxis in ['z', 'Z']:
44 | worldUpVector = (0, 0, 1)
45 |
46 | # fk skeleton chain
47 | # create FK crv
48 | ik_part_list = []
49 | ik_part_list = cmds.ikHandle(sj=spineJoints[0], ee=spineJoints[-1], parentCurve=1, sol='ikSplineSolver', numSpans=4,
50 | simplifyCurve=0)
51 |
52 | cmds.delete(ik_part_list[0])
53 |
54 | FK_Crv = ik_part_list[-1]
55 |
56 | fkJntList = []
57 | eachADD = 1.0 / (len(range(numFK_Jnt)) - 1)
58 |
59 | for i in range(numFK_Jnt):
60 | fkJnt = cmds.joint(n='FK_' + prefix + rigPartName + '_' + str(i))
61 | pc = cmds.parentConstraint(spineJoints[0], fkJnt, mo=0)
62 | cmds.delete(pc)
63 |
64 | motionPath = cmds.pathAnimation(FK_Crv, fkJnt, n=fkJnt + '_motionPath', fractionMode=1, follow=1,
65 | followAxis='x', upAxis='y', worldUpType='Vector',
66 | worldUpVector=worldUpVector, inverseUp=0, inverseFront=0, bank=0)
67 |
68 | # cmds.disconnectAttr(motionPath + '_uValue.output', motionPath + '.uValue')
69 | cmds.cutKey(motionPath + '.u', time=())
70 |
71 | cmds.setAttr(motionPath + '.uValue', eachADD * float(i))
72 |
73 | for attr in ['t', 'r']:
74 | for axis in ['x', 'y', 'z']:
75 | cmds.delete(fkJnt + '.%s%s' % (attr, axis), icn=1)
76 |
77 | cmds.delete(motionPath)
78 |
79 | cmds.select(cl=1)
80 |
81 | fkJntList.append(fkJnt)
82 |
83 | # delete the motionPath
84 | cmds.delete(FK_Crv)
85 |
86 | # move the last fk joint to the end of the spineJoints
87 | pc3 = cmds.pointConstraint(spineJoints[-1], fkJntList[-1], mo=0)
88 | cmds.delete(pc3)
89 |
90 | # aimConstraint all the fk_joints, the last joints must be same direction as the last joints of original joints list
91 | fkJntList_rev = []
92 |
93 | for i in fkJntList:
94 | fkJntList_rev.append(i)
95 | fkJntList_rev.reverse()
96 |
97 | for i in xrange(len(fkJntList_rev)-1):
98 | ac = cmds.aimConstraint(fkJntList_rev[i], fkJntList_rev[i+1], mo=0, weight=1, aimVector=(1, 0, 0),
99 | upVector=(0, 1, 0), worldUpType='vector', worldUpVector=worldUpVector)
100 | cmds.delete(ac)
101 |
102 | # orientConstraint the last joint
103 | oc = cmds.orientConstraint(spineJoints[-1], fkJntList_rev[0], mo=0)
104 | cmds.delete(oc)
105 |
106 | # parent
107 | for i in xrange(len(fkJntList_rev)-1):
108 | cmds.parent(fkJntList_rev[i], fkJntList_rev[i+1])
109 |
110 | # set fk joints drawStyle to None and display to template
111 |
112 | for i in fkJntList:
113 | cmds.setAttr(i + '.drawStyle', 2)
114 |
115 | # freeze transformation
116 | cmds.makeIdentity(fkJntList[0], apply=1)
117 |
118 |
119 | ##########
120 | # FK rig #
121 | ##########
122 | FK_CtrlGrp_List = []
123 | FK_Ctrl_List = []
124 |
125 | for i in xrange(len(fkJntList)-2):
126 | FK_C_Spine_Ctrl = control.Control(prefix=prefix + 'FK_',
127 | rigPartName=rigPartName + '_' + str(i),
128 | scale=rigScale,
129 | translateTo=fkJntList[i+1],
130 | rotateTo=fkJntList[i+1],
131 | shape='circle',
132 | lockChannels=['t', 's', 'v'])
133 |
134 | cmds.orientConstraint(FK_C_Spine_Ctrl.C, fkJntList[i+1], mo=0)
135 |
136 | FK_CtrlGrp_List.append(FK_C_Spine_Ctrl.Off)
137 | FK_Ctrl_List.append(FK_C_Spine_Ctrl.C)
138 |
139 | cmds.select(cl=1)
140 |
141 | # parent the CtrlGrps to the proper places
142 | for i in xrange(len(FK_Ctrl_List)-1):
143 | cmds.parent(FK_CtrlGrp_List[i+1], FK_Ctrl_List[i])
144 |
145 | cmds.parent(FK_CtrlGrp_List[0], fkJntList[0])
146 |
147 | #############
148 | # Body Ctrl #
149 | #############
150 |
151 | if not mainSpineAttach:
152 | # create a square control shape for body ctrl
153 | body_Ctrl = control.Control(prefix=prefix,
154 | rigPartName='Body',
155 | scale=rigScale * 15,
156 | shape='squareControl',
157 | translateTo=spineJoints[0],
158 | axis='z')
159 | else:
160 | body_Loc = cmds.spaceLocator(n=prefix + rigPartName + '_Loc')
161 | body_LocShape = cmds.listRelatives(body_Loc, s=1)
162 | cmds.setAttr(body_LocShape[0] + '.localScaleX', 0)
163 | cmds.setAttr(body_LocShape[0] + '.localScaleY', 0)
164 | cmds.setAttr(body_LocShape[0] + '.localScaleZ', 0)
165 | cmds.parentConstraint(mainSpineAttach, body_Loc, mo=0)
166 |
167 | C_Pelvis_Ctrl = control.Control(prefix=prefix,
168 | rigPartName='Pelvis',
169 | scale=rigScale*2,
170 | translateTo=spineJoints[0],
171 | rotateTo=spineJoints[0],
172 | axis='x',
173 | shape='moveControl')
174 |
175 | C_Chest_Ctrl = control.Control(prefix=prefix,
176 | rigPartName='Chest',
177 | scale=rigScale*3,
178 | translateTo=spineJoints[-1],
179 | rotateTo=spineJoints[-1],
180 | axis='x',
181 | shape='moveControl')
182 |
183 | # create 2 joints for controlling ikHandle curve
184 | pelvis_Jnt = cmds.joint(n=prefix + 'Pelvis')
185 | cmds.select(cl=1)
186 | cmds.setAttr(pelvis_Jnt + '.v', 0)
187 | chest_Jnt = cmds.joint(n=prefix + 'Chest')
188 | cmds.select(cl=1)
189 | cmds.setAttr(chest_Jnt + '.v', 0)
190 |
191 | pc1 = cmds.parentConstraint(fkJntList[0], pelvis_Jnt, mo=0)
192 | cmds.delete(pc1)
193 | cmds.makeIdentity(pelvis_Jnt, apply=1)
194 |
195 | pc2 = cmds.parentConstraint(fkJntList[-1], chest_Jnt, mo=0)
196 | cmds.delete(pc2)
197 | cmds.makeIdentity(chest_Jnt, apply=1)
198 |
199 | ##########
200 | # IK rig #
201 | ##########
202 |
203 | IK_Part_List = cmds.ikHandle(n=prefix + rigPartName + '_IK',
204 | sj=spineJoints[0],
205 | ee=spineJoints[-1],
206 | parentCurve=0,
207 | numSpans=4,
208 | sol='ikSplineSolver')
209 |
210 | # bind ik curve with 2 joints
211 | cmds.select(cl=1)
212 | cmds.select(IK_Part_List[-1])
213 | cmds.select(chest_Jnt, add=1)
214 | cmds.select(pelvis_Jnt, add=1)
215 | cmds.skinCluster(chest_Jnt, pelvis_Jnt, IK_Part_List[-1], tsb=1)
216 |
217 | # setup IK Twist
218 | cmds.setAttr(IK_Part_List[0] + '.dTwistControlEnable', 1)
219 | cmds.setAttr(IK_Part_List[0] + '.dWorldUpType', 4)
220 | cmds.connectAttr(C_Pelvis_Ctrl.C + '.worldMatrix[0]', IK_Part_List[0] + '.dWorldUpMatrix')
221 | cmds.connectAttr(C_Chest_Ctrl.C + '.worldMatrix[0]', IK_Part_List[0] + '.dWorldUpMatrixEnd')
222 |
223 | # add attr
224 | for joint in spineJoints:
225 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
226 | cmds.addAttr(joint, ln='slaveJoint', at='message')
227 |
228 | if not cmds.attributeQuery('rigModule', node=joint, exists=1):
229 | cmds.addAttr(joint, ln='rigModule', at='message')
230 |
231 | # connect attr
232 | for joint in spineJoints:
233 | if cmds.attributeQuery('rigModule', node=joint, exists=1):
234 | cmds.connectAttr(rigModule.topGrp + '.' + prefix + rigPartName + "_Jnt",
235 | joint + '.rigModule', f=1)
236 |
237 | # clean up the hierarchy
238 | cmds.parent(pelvis_Jnt, C_Pelvis_Ctrl.C)
239 | cmds.parent(chest_Jnt, C_Chest_Ctrl.C)
240 |
241 | # parent fk_jnt to body_Ctrl
242 | if not mainSpineAttach:
243 | cmds.parent(fkJntList[0], body_Ctrl.C)
244 |
245 | # parent pelvis_CtrlGrp to body_Ctrl
246 | cmds.parent(C_Pelvis_Ctrl.Off, body_Ctrl.C)
247 | else:
248 | cmds.parent(fkJntList[0], body_Loc)
249 | cmds.parent(C_Pelvis_Ctrl.Off, body_Loc)
250 |
251 |
252 | # parent chest_CtrlGrp to fkJntList[-1]
253 | cmds.parent(C_Chest_Ctrl.Off, fkJntList[-1])
254 |
255 | cmds.parent(IK_Part_List[-1], IK_Part_List[0], rigModule.dontTouchGrp)
256 |
257 | # parent body_CtrlGrp to rigmodule.topGrp
258 | if not mainSpineAttach:
259 | cmds.parent(body_Ctrl.Off, rigModule.topGrp)
260 | else:
261 | cmds.parent(body_Loc, rigModule.topGrp)
262 |
263 | cmds.select(cl=1)
264 |
265 | # rootJoint
266 | rootJnt = ''
267 | if not mainSpineAttach:
268 | rootJnt = cmds.listRelatives(spineJoints[0], p=1, c=0, s=0, type='joint')
269 |
270 | if rootJnt:
271 |
272 | if not cmds.attributeQuery('slaveJoint', node=rootJnt[0], exists=1):
273 | cmds.addAttr(rootJnt[0], ln='slaveJoint', at='message')
274 |
275 | if not cmds.attributeQuery('rootJoint', node=rootJnt[0], exists=1):
276 | cmds.addAttr(rootJnt[0], ln='rootJoint', at='message')
277 |
278 |
279 | # return
280 | return {'chest_Ctrl': C_Chest_Ctrl.C,
281 | 'pelvis_Ctrl': C_Pelvis_Ctrl.C,
282 | 'rootJnt': rootJnt[0],
283 | 'rigModule': rigModule}
284 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/base/controlShape/RotationControl.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 |
4 | def createShape(prefix='', scale=1.0):
5 | List = []
6 | List.append(cmds.curve(n=prefix, p=[(0.33587352900359235, 3.552713678800501e-15, 0.7361468691490706), (0.4304251528553422, 0.03022134593976844, 0.6908148502394227), (0.5107046042608197, 0.07247276978952044, 0.6274377144647979), (0.5684975545498538, 0.12400997464880348, 0.5501319071758723), (0.5684975545498538, 0.12400997464880348, 0.5501319071758723), (0.5684975545498538, 0.12400997464880348, 0.5501319071758723), (0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (0.5402530010360955, 0.08197748359885182, 0.5946770761304137), (0.4852738226242117, 0.0455134352238602, 0.6467685738089757), (0.41921829926566545, 0.015501246831103543, 0.6896431286557706), (0.41921829926566545, 0.015501246831103543, 0.6896431286557706), (0.41921829926566545, 0.015501246831103543, 0.6896431286557706), (0.7077292503941841, 0.015501246831103543, 0.43808875481816606), (0.8080009216827335, 0.015501246831103543, -0.016811817720621902), (0.6943482219457628, 0.015501246831103543, -0.34108941639861884), (0.5527220271320097, 0.015501246831103543, -0.5148315398676033), (0.33489352471512746, 0.015501246831103543, -0.6771644412642893), (0.17585601860228905, 0.015501246831103543, -0.7201406688717121), (0.015501247071298963, 0.015501246831103543, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
7 | List.append(cmds.curve(p=[(0.33587352900359235, -3.552713678800501e-15, 0.7361468691490706), (0.4304251528553422, -0.03022134593976844, 0.6908148502394227), (0.5107046042608197, -0.07247276978952044, 0.6274377144647979), (0.5684975545498538, -0.12400997464880348, 0.5501319071758723), (0.5684975545498538, -0.12400997464880348, 0.5501319071758723), (0.5684975545498538, -0.12400997464880348, 0.5501319071758723), (0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (0.5402530010360955, -0.08197748359885182, 0.5946770761304137), (0.4852738226242117, -0.0455134352238602, 0.6467685738089757), (0.41921829926566545, -0.015501246831103543, 0.6896431286557706), (0.41921829926566545, -0.015501246831103543, 0.6896431286557706), (0.41921829926566545, -0.015501246831103543, 0.6896431286557706), (0.7077292503941841, -0.015501246831103543, 0.43808875481816606), (0.8080009216827335, -0.015501246831103543, -0.016811817720621902), (0.6943482219457628, -0.015501246831103543, -0.34108941639861884), (0.5527220271320097, -0.015501246831103543, -0.5148315398676033), (0.33489352471512746, -0.015501246831103543, -0.6771644412642893), (0.17585601860228905, -0.015501246831103543, -0.7201406688717121), (0.015501247071298963, -0.015501246831103543, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
8 | List.append(cmds.curve(p=[(-0.33587352900359235, 3.552713678800501e-15, 0.7361468691490706), (-0.4304251528553422, 0.03022134593976844, 0.6908148502394227), (-0.5107046042608197, 0.07247276978952044, 0.6274377144647979), (-0.5684975545498538, 0.12400997464880348, 0.5501319071758723), (-0.5684975545498538, 0.12400997464880348, 0.5501319071758723), (-0.5684975545498538, 0.12400997464880348, 0.5501319071758723), (-0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (-0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (-0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (-0.5819931861859438, 0.12400997464880348, 0.5346306603447717), (-0.5402530010360955, 0.08197748359885182, 0.5946770761304137), (-0.4852738226242117, 0.0455134352238602, 0.6467685738089757), (-0.41921829926566545, 0.015501246831103543, 0.6896431286557706), (-0.41921829926566545, 0.015501246831103543, 0.6896431286557706), (-0.41921829926566545, 0.015501246831103543, 0.6896431286557706), (-0.7077292503941841, 0.015501246831103543, 0.43808875481816606), (-0.8080009216827335, 0.015501246831103543, -0.016811817720621902), (-0.6943482219457628, 0.015501246831103543, -0.34108941639861884), (-0.5527220271320097, 0.015501246831103543, -0.5148315398676033), (-0.33489352471512746, 0.015501246831103543, -0.6771644412642893), (-0.17585601860228905, 0.015501246831103543, -0.7201406688717121), (-0.015501247071298963, 0.015501246831103543, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
9 | List.append(cmds.curve(p=[(-0.33587352900359235, -3.552713678800501e-15, 0.7361468691490706), (-0.4304251528553422, -0.03022134593976844, 0.6908148502394227), (-0.5107046042608197, -0.07247276978952044, 0.6274377144647979), (-0.5684975545498538, -0.12400997464880348, 0.5501319071758723), (-0.5684975545498538, -0.12400997464880348, 0.5501319071758723), (-0.5684975545498538, -0.12400997464880348, 0.5501319071758723), (-0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (-0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (-0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (-0.5819931861859438, -0.12400997464880348, 0.5346306603447717), (-0.5402530010360955, -0.08197748359885182, 0.5946770761304137), (-0.4852738226242117, -0.0455134352238602, 0.6467685738089757), (-0.41921829926566545, -0.015501246831103543, 0.6896431286557706), (-0.41921829926566545, -0.015501246831103543, 0.6896431286557706), (-0.41921829926566545, -0.015501246831103543, 0.6896431286557706), (-0.7077292503941841, -0.015501246831103543, 0.43808875481816606), (-0.8080009216827335, -0.015501246831103543, -0.016811817720621902), (-0.6943482219457628, -0.015501246831103543, -0.34108941639861884), (-0.5527220271320097, -0.015501246831103543, -0.5148315398676033), (-0.33489352471512746, -0.015501246831103543, -0.6771644412642893), (-0.17585601860228905, -0.015501246831103543, -0.7201406688717121), (-0.015501247071298963, -0.015501246831103543, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
10 | List.append(cmds.curve(p=[(-7.105427357601002e-15, -0.3358735290035888, 0.7361468691490706), (-0.030221345939771993, -0.43042515285533867, 0.6908148502394227), (-0.072472769789524, -0.5107046042608161, 0.6274377144647979), (-0.12400997464880703, -0.5684975545498503, 0.5501319071758723), (-0.12400997464880703, -0.5684975545498503, 0.5501319071758723), (-0.12400997464880703, -0.5684975545498503, 0.5501319071758723), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.12400997464880703, -0.5819931861859402, 0.5346306603447717), (-0.08197748359885537, -0.540253001036092, 0.5946770761304137), (-0.04551343522386375, -0.48527382262420815, 0.6467685738089757), (-0.015501246831107096, -0.4192182992656619, 0.6896431286557706), (-0.015501246831107096, -0.4192182992656619, 0.6896431286557706), (-0.015501246831107096, -0.4192182992656619, 0.6896431286557706), (-0.015501246831107096, -0.7077292503941806, 0.43808875481816606), (-0.015501246831107096, -0.80800092168273, -0.016811817720621902), (-0.015501246831107096, -0.6943482219457593, -0.34108941639861884), (-0.015501246831107096, -0.5527220271320061, -0.5148315398676033), (-0.015501246831107096, -0.3348935247151239, -0.6771644412642893), (-0.015501246831107096, -0.1758560186022855, -0.7201406688717121), (-0.015501246831107096, -0.01550124707129541, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
11 | List.append(cmds.curve(p=[(3.552713678800501e-15, -0.3358735290035959, 0.7361468691490706), (0.03022134593976844, -0.43042515285534577, 0.6908148502394227), (0.07247276978952044, -0.5107046042608232, 0.6274377144647979), (0.12400997464880348, -0.5684975545498574, 0.5501319071758723), (0.12400997464880348, -0.5684975545498574, 0.5501319071758723), (0.12400997464880348, -0.5684975545498574, 0.5501319071758723), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.12400997464880348, -0.5819931861859473, 0.5346306603447717), (0.08197748359885182, -0.5402530010360991, 0.5946770761304137), (0.0455134352238602, -0.48527382262421526, 0.6467685738089757), (0.015501246831103543, -0.419218299265669, 0.6896431286557706), (0.015501246831103543, -0.419218299265669, 0.6896431286557706), (0.015501246831103543, -0.419218299265669, 0.6896431286557706), (0.015501246831103543, -0.7077292503941877, 0.43808875481816606), (0.015501246831103543, -0.8080009216827371, -0.016811817720621902), (0.015501246831103543, -0.6943482219457664, -0.34108941639861884), (0.015501246831103543, -0.5527220271320132, -0.5148315398676033), (0.015501246831103543, -0.334893524715131, -0.6771644412642893), (0.015501246831103543, -0.1758560186022926, -0.7201406688717121), (0.015501246831103543, -0.015501247071302515, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
12 | List.append(cmds.curve(p=[(0.0, 0.33587352900359235, 0.7361468691490706), (-0.030221345939764888, 0.4304251528553422, 0.6908148502394227), (-0.07247276978951689, 0.5107046042608197, 0.6274377144647979), (-0.12400997464879993, 0.5684975545498538, 0.5501319071758723), (-0.12400997464879993, 0.5684975545498538, 0.5501319071758723), (-0.12400997464879993, 0.5684975545498538, 0.5501319071758723), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.12400997464879993, 0.5819931861859438, 0.5346306603447717), (-0.08197748359884827, 0.5402530010360955, 0.5946770761304137), (-0.045513435223856646, 0.4852738226242117, 0.6467685738089757), (-0.01550124683109999, 0.41921829926566545, 0.6896431286557706), (-0.01550124683109999, 0.41921829926566545, 0.6896431286557706), (-0.01550124683109999, 0.41921829926566545, 0.6896431286557706), (-0.01550124683109999, 0.7077292503941841, 0.43808875481816606), (-0.01550124683109999, 0.8080009216827335, -0.016811817720621902), (-0.01550124683109999, 0.6943482219457628, -0.34108941639861884), (-0.01550124683109999, 0.5527220271320097, -0.5148315398676033), (-0.01550124683109999, 0.33489352471512746, -0.6771644412642893), (-0.01550124683109999, 0.17585601860228905, -0.7201406688717121), (-0.01550124683109999, 0.015501247071298963, -0.7361468691392242)],per = False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
13 | List.append(cmds.curve(p=[(3.552713678800501e-15, 0.33587352900359235, 0.7361468691490706), (0.03022134593976844, 0.4304251528553422, 0.6908148502394227), (0.07247276978952044, 0.5107046042608197, 0.6274377144647979), (0.12400997464880348, 0.5684975545498538, 0.5501319071758723), (0.12400997464880348, 0.5684975545498538, 0.5501319071758723), (0.12400997464880348, 0.5684975545498538, 0.5501319071758723), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.12400997464880348, 0.5819931861859438, 0.5346306603447717), (0.08197748359885182, 0.5402530010360955, 0.5946770761304137), (0.0455134352238602, 0.4852738226242117, 0.6467685738089757), (0.015501246831103543, 0.41921829926566545, 0.6896431286557706), (0.015501246831103543, 0.41921829926566545, 0.6896431286557706), (0.015501246831103543, 0.41921829926566545, 0.6896431286557706), (0.015501246831103543, 0.7077292503941841, 0.43808875481816606), (0.015501246831103543, 0.8080009216827335, -0.016811817720621902), (0.015501246831103543, 0.6943482219457628, -0.34108941639861884), (0.015501246831103543, 0.5527220271320097, -0.5148315398676033), (0.015501246831103543, 0.33489352471512746, -0.6771644412642893), (0.015501246831103543, 0.17585601860228905, -0.7201406688717121), (0.015501246831103543, 0.015501247071298963, -0.7361468691392242)], per=False, d=3, k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 19]))
14 |
15 | for x in range(len(List)-1):
16 | cmds.makeIdentity(List[x+1],apply=True,t=1,r=1,s=1,n=0)
17 | shapeNode = cmds.listRelatives(List[x+1], shapes=True)
18 | cmds.parent(shapeNode, List[0], add=True, s=True)
19 | cmds.delete(List[x+1])
20 | sel = List[0]
21 | cmds.setAttr(sel + '.s', scale, scale, scale)
22 | cmds.makeIdentity(sel, apply=1, t=1, r=1, s=1, n=0)
23 | return sel
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/IK_FK_Head_Neck.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 | from ..base import module
3 | from ..base import control
4 | reload(module)
5 | reload(control)
6 |
7 |
8 | def build(neckJoints,
9 | Neck_Parent='',
10 | rigScale=1.0,
11 | prefix='C_',
12 | blendCtrl_Pos='',
13 | baseRig=None
14 | ):
15 | """
16 | Build the IK_FK_Neck rig.
17 | :param neckJoints: list(str), neck joints and head joint list, [neck_0, neck_1, ... neck_#, head, head_end]
18 | :param Neck_Parent: str, Neck parent joint, it's usually the last valid joint of the spine joints(i.e. Spine_#)
19 | :param rigScale: float, rig scale of the control
20 | :param prefix: str, 'C_', 'L_' or 'R_'
21 | :param blendCtrl_Pos: str, space locator
22 | :param baseRig: str, base atttach of the rig, Base Class instance is used.
23 | :return: None
24 | """
25 | if Neck_Parent:
26 | try:
27 | cmds.objectType(Neck_Parent) == 'joint'
28 | pass
29 | except:
30 | cmds.error('%s is not a joint, please check again' % Neck_Parent)
31 |
32 | else:
33 | parentJnt = cmds.listRelatives(neckJoints[0], s=0, c=0, parent=1, type='joint')
34 | if parentJnt:
35 | Neck_Parent = parentJnt
36 | else:
37 | cmds.warning('No parent jnt of %s, IK may not work as expected!' % neckJoints[0])
38 |
39 | cmds.select(cl=1)
40 |
41 | rigPartName = 'Head'
42 |
43 | rigModule = module.Module(prefix=prefix,
44 | rigPartName=rigPartName,
45 | baseObject=baseRig)
46 |
47 | cmds.select(cl=1)
48 |
49 | # duplicate the specified joints
50 | # create fk joints list
51 | fk_Joints_List = []
52 | fkHeadJnts_Dirty_Start = cmds.duplicate(neckJoints[0], n='FK_' + neckJoints[0], renameChildren=1)
53 | fk_Joints_List.append(fkHeadJnts_Dirty_Start[0])
54 | fkHeadJnts_Dirty_Children = cmds.listRelatives(fkHeadJnts_Dirty_Start, s=0, parent=0, children=1, type='joint')
55 |
56 | for i in range(len(fkHeadJnts_Dirty_Children)):
57 | rename_Jnt = cmds.rename(fkHeadJnts_Dirty_Children[i], 'FK_' + neckJoints[i+1])
58 | fk_Joints_List.append(rename_Jnt)
59 |
60 | cmds.setAttr(fk_Joints_List[0] + '.v', 0)
61 | cmds.select(cl=1)
62 |
63 | # create ik joints list
64 | ik_Joints_List = []
65 | ikHeadJnts_Dirty_Start = cmds.duplicate(neckJoints[0], n='IK_' + neckJoints[0], renameChildren=1)
66 | ik_Joints_List.append(ikHeadJnts_Dirty_Start[0])
67 | ikHeadJnts_Dirty_Children = cmds.listRelatives(ikHeadJnts_Dirty_Start, s=0, parent=0, children=1, type='joint')
68 |
69 | for i in range(len(ikHeadJnts_Dirty_Children)):
70 | rename_Jnt = cmds.rename(ikHeadJnts_Dirty_Children[i], 'IK_' + neckJoints[i+1])
71 | ik_Joints_List.append(rename_Jnt)
72 |
73 | cmds.setAttr(ik_Joints_List[0] + '.v', 0)
74 | cmds.select(cl=1)
75 |
76 | ##########
77 | # FK Rig #
78 | ##########
79 |
80 | FK_Neck_CtrlGrp_List = []
81 | FK_Neck_Ctrl_List = []
82 |
83 | for i in xrange(len(fk_Joints_List)-2):
84 | FK_Neck_Ctrl = control.Control(prefix=prefix + 'FK_',
85 | rigPartName='Neck_' + str(i),
86 | scale=rigScale,
87 | translateTo=fk_Joints_List[i],
88 | rotateTo=fk_Joints_List[i],
89 | shape='arrowCurve',
90 | axis='x',
91 | lockChannels=['t', 's', 'v']
92 | )
93 | cmds.orientConstraint(FK_Neck_Ctrl.C, fk_Joints_List[i], mo=0)
94 |
95 | FK_Neck_CtrlGrp_List.append(FK_Neck_Ctrl.Off)
96 | FK_Neck_Ctrl_List.append(FK_Neck_Ctrl.C)
97 |
98 | cmds.select(cl=1)
99 |
100 | # parent the CtrlGrps to the proper places
101 | for i in xrange(len(FK_Neck_Ctrl_List)-1):
102 | cmds.parent(FK_Neck_CtrlGrp_List[i+1], FK_Neck_Ctrl_List[i])
103 |
104 | FK_Head_Ctrl = control.Control(prefix=prefix + 'FK_',
105 | rigPartName=rigPartName,
106 | scale=rigScale,
107 | translateTo=fk_Joints_List[-2],
108 | rotateTo=fk_Joints_List[-2],
109 | shape='cubeOnBase',
110 | axis='x',
111 | lockChannels=['t', 's', 'v'])
112 |
113 | # Local LOC
114 | fk_headLocal = cmds.spaceLocator(n='FK_' + prefix + rigPartName + '_Local')
115 | fk_headLocal_Shape = cmds.listRelatives(fk_headLocal, s=1)
116 | cmds.setAttr(fk_headLocal_Shape[0] + '.localScaleX', 0)
117 | cmds.setAttr(fk_headLocal_Shape[0] + '.localScaleY', 0)
118 | cmds.setAttr(fk_headLocal_Shape[0] + '.localScaleZ', 0)
119 | cmds.setAttr(fk_headLocal_Shape[0] + '.template', 1)
120 |
121 | # World LOC
122 | fk_headWorld = cmds.spaceLocator(n='FK_' + prefix + rigPartName + '_World')
123 | fk_headWorld_Shape = cmds.listRelatives(fk_headWorld, s=1)
124 | cmds.setAttr(fk_headWorld_Shape[0] + '.localScaleX', 0)
125 | cmds.setAttr(fk_headWorld_Shape[0] + '.localScaleY', 0)
126 | cmds.setAttr(fk_headWorld_Shape[0] + '.localScaleZ', 0)
127 | cmds.setAttr(fk_headWorld_Shape[0] + '.template', 1)
128 |
129 | cmds.delete(cmds.parentConstraint(fk_Joints_List[-2], fk_headLocal, mo=0))
130 | cmds.delete(cmds.parentConstraint(fk_Joints_List[-2], fk_headWorld, mo=0))
131 |
132 | FK_Head_OrientConstraint = cmds.orientConstraint(fk_headLocal, fk_headWorld, FK_Head_Ctrl.Off, mo=0)
133 | cmds.pointConstraint(fk_headLocal, FK_Head_Ctrl.Off, mo=0)
134 |
135 | # create attr and setDrivenKey
136 | cmds.addAttr(FK_Head_Ctrl.C, ln='Local2World', at="float", min=0, max=1, dv=0, k=1)
137 | cmds.setAttr(FK_Head_Ctrl.C + '.Local2World', 0)
138 | cmds.setAttr(FK_Head_OrientConstraint[0] + '.' + fk_headLocal[0] + 'W0', 1)
139 | cmds.setAttr(FK_Head_OrientConstraint[0] + '.' + fk_headWorld[0] + 'W1', 0)
140 |
141 | cmds.setDrivenKeyframe(FK_Head_OrientConstraint[0] + '.' + fk_headLocal[0] + 'W0',
142 | cd=FK_Head_Ctrl.C + '.Local2World')
143 | cmds.setDrivenKeyframe(FK_Head_OrientConstraint[0] + '.' + fk_headWorld[0] + 'W1',
144 | cd=FK_Head_Ctrl.C + '.Local2World')
145 |
146 | cmds.setAttr(FK_Head_Ctrl.C + '.Local2World', 1)
147 | cmds.setAttr(FK_Head_OrientConstraint[0] + '.' + fk_headLocal[0] + 'W0', 0)
148 | cmds.setAttr(FK_Head_OrientConstraint[0] + '.' + fk_headWorld[0] + 'W1', 1)
149 |
150 | cmds.setDrivenKeyframe(FK_Head_OrientConstraint[0] + '.' + fk_headLocal[0] + 'W0',
151 | cd=FK_Head_Ctrl.C + '.Local2World')
152 | cmds.setDrivenKeyframe(FK_Head_OrientConstraint[0] + '.' + fk_headWorld[0] + 'W1',
153 | cd=FK_Head_Ctrl.C + '.Local2World')
154 |
155 | # point and orient constriant the fk head joint
156 | cmds.pointConstraint(FK_Head_Ctrl.C, fk_Joints_List[-2], mo=0)
157 | cmds.orientConstraint(FK_Head_Ctrl.C, fk_Joints_List[-2], mo=1)
158 |
159 | ##########
160 | # IK Rig #
161 | ##########
162 | IK_Head_Ctrl = control.Control(prefix=prefix + 'IK_',
163 | rigPartName=rigPartName,
164 | scale=rigScale,
165 | translateTo=ik_Joints_List[-2],
166 | rotateTo=ik_Joints_List[-2],
167 | shape='moveControl',
168 | axis='x')
169 |
170 | IK_Start_Jnt = cmds.joint(n='IK_' + prefix + rigPartName + '_StartJnt')
171 | cmds.select(cl=1)
172 | IK_End_Jnt = cmds.joint(n='IK_' + prefix + rigPartName + '_EndJnt')
173 | cmds.select(cl=1)
174 | cmds.delete(cmds.parentConstraint(neckJoints[0], IK_Start_Jnt, mo=0))
175 | cmds.delete(cmds.parentConstraint(neckJoints[-2], IK_End_Jnt, mo=0))
176 |
177 | cmds.makeIdentity(IK_Start_Jnt, apply=1, t=1, r=1, s=1, n=0, pn=1)
178 | cmds.makeIdentity(IK_End_Jnt, apply=1, t=1, r=1, s=1, n=0, pn=1)
179 |
180 | cmds.select(cl=1)
181 | cmds.parent(IK_End_Jnt, IK_Head_Ctrl.C)
182 |
183 | if Neck_Parent:
184 | cmds.parent(IK_Start_Jnt, Neck_Parent)
185 | else:
186 | cmds.parent(IK_Start_Jnt, rigModule.topGrp)
187 |
188 | cmds.setAttr(IK_Start_Jnt + '.v', 0)
189 | cmds.setAttr(IK_End_Jnt + '.v', 0)
190 |
191 | # ik handle
192 | IK_Part_List = cmds.ikHandle(n=prefix + rigPartName + '_IK',
193 | sj=ik_Joints_List[0],
194 | ee=ik_Joints_List[-2],
195 | sol='ikSplineSolver',
196 | pcv=0,
197 | numSpans=4)
198 |
199 | cmds.select(cl=1)
200 | cmds.select(IK_Part_List[-1])
201 | cmds.select(IK_Start_Jnt, add=1)
202 | cmds.select(IK_End_Jnt, add=1)
203 | cmds.skinCluster(IK_Start_Jnt, IK_End_Jnt, IK_Part_List[-1], tsb=1)
204 | cmds.select(cl=1)
205 |
206 | # setup IK Twist
207 | cmds.setAttr(IK_Part_List[0] + '.dTwistControlEnable', 1)
208 | cmds.setAttr(IK_Part_List[0] + '.dWorldUpType', 4)
209 | cmds.connectAttr(IK_Start_Jnt + '.worldMatrix[0]', IK_Part_List[0] + '.dWorldUpMatrix')
210 | cmds.connectAttr(IK_End_Jnt + '.worldMatrix[0]', IK_Part_List[0] + '.dWorldUpMatrixEnd')
211 |
212 | # create ik_head_local and ik_head_world
213 | ik_headLocal = cmds.spaceLocator(n='IK_' + prefix + rigPartName + '_Local')
214 | ik_headLocal_Shape = cmds.listRelatives(ik_headLocal, s=1)
215 | cmds.setAttr(ik_headLocal_Shape[0] + '.localScaleX', 0)
216 | cmds.setAttr(ik_headLocal_Shape[0] + '.localScaleY', 0)
217 | cmds.setAttr(ik_headLocal_Shape[0] + '.localScaleZ', 0)
218 | cmds.setAttr(ik_headLocal_Shape[0] + '.template', 1)
219 |
220 | ik_headWorld = cmds.spaceLocator(n='IK_' + prefix + rigPartName + '_World')
221 | ik_headWorld_Shape = cmds.listRelatives(ik_headWorld, s=1)
222 | cmds.setAttr(ik_headWorld_Shape[0] + '.localScaleX', 0)
223 | cmds.setAttr(ik_headWorld_Shape[0] + '.localScaleY', 0)
224 | cmds.setAttr(ik_headWorld_Shape[0] + '.localScaleZ', 0)
225 | cmds.setAttr(ik_headWorld_Shape[0] + '.template', 1)
226 |
227 | cmds.delete(cmds.parentConstraint(ik_Joints_List[-2], ik_headLocal, mo=0))
228 | cmds.delete(cmds.parentConstraint(ik_Joints_List[-2], ik_headWorld, mo=0))
229 |
230 | IK_Head_OrientConstraint = cmds.orientConstraint(ik_headLocal, ik_headWorld, IK_Head_Ctrl.Off, mo=0)
231 |
232 | # create attr and setDrivenKey
233 | cmds.addAttr(IK_Head_Ctrl.C, ln='Local2World', at="float", min=0, max=1, dv=0, k=1)
234 |
235 | cmds.setAttr(IK_Head_Ctrl.C + '.Local2World', 0)
236 | cmds.setAttr(IK_Head_OrientConstraint[0] + '.' + ik_headLocal[0] + 'W0', 1)
237 | cmds.setAttr(IK_Head_OrientConstraint[0] + '.' + ik_headWorld[0] + 'W1', 0)
238 |
239 | cmds.setDrivenKeyframe(IK_Head_OrientConstraint[0] + '.' + ik_headLocal[0] + 'W0',
240 | cd=IK_Head_Ctrl.C + '.Local2World')
241 | cmds.setDrivenKeyframe(IK_Head_OrientConstraint[0] + '.' + ik_headWorld[0] + 'W1',
242 | cd=IK_Head_Ctrl.C + '.Local2World')
243 |
244 | cmds.setAttr(IK_Head_Ctrl.C + '.Local2World', 1)
245 | cmds.setAttr(IK_Head_OrientConstraint[0] + '.' + ik_headLocal[0] + 'W0', 0)
246 | cmds.setAttr(IK_Head_OrientConstraint[0] + '.' + ik_headWorld[0] + 'W1', 1)
247 |
248 | cmds.setDrivenKeyframe(IK_Head_OrientConstraint[0] + '.' + ik_headLocal[0] + 'W0',
249 | cd=IK_Head_Ctrl.C + '.Local2World')
250 | cmds.setDrivenKeyframe(IK_Head_OrientConstraint[0] + '.' + ik_headWorld[0] + 'W1',
251 | cd=IK_Head_Ctrl.C + '.Local2World')
252 |
253 | # IK FK BLEND
254 | IK_FK_BlendCtrl = control.Control(prefix=prefix,
255 | rigPartName=rigPartName + '_Blend',
256 | scale=rigScale*5,
257 | translateTo=blendCtrl_Pos,
258 | rotateTo=blendCtrl_Pos,
259 | shape='unitSliderControl',
260 | lockChannels=['tx', 'tz', 'r', 's', 'v'])
261 |
262 | for i in range(len(fk_Joints_List)):
263 | # blend node
264 | blend = cmds.createNode('blendColors')
265 | # ik
266 | cmds.connectAttr(ik_Joints_List[i] + '.r', blend + '.color1', f=1)
267 | # fk
268 | cmds.connectAttr(fk_Joints_List[i] + '.r', blend + '.color2', f=1)
269 | # output to origin neckJoints
270 | cmds.connectAttr(blend + '.output', neckJoints[i] + '.r', f=1)
271 | # IK_FK_BlendCtrl
272 | cmds.connectAttr(IK_FK_BlendCtrl.C + '.ty', blend + '.blender')
273 |
274 | # visibility blend
275 | cmds.setAttr(IK_FK_BlendCtrl.C + '.ty', 0)
276 | cmds.setAttr(FK_Neck_CtrlGrp_List[0] + '.v', 1)
277 | cmds.setAttr(FK_Head_Ctrl.Off + '.v', 1)
278 | cmds.setAttr(IK_Head_Ctrl.Off + '.v', 0)
279 |
280 | cmds.setDrivenKeyframe(FK_Neck_CtrlGrp_List[0] + '.v', cd=IK_FK_BlendCtrl.C + '.ty')
281 | cmds.setDrivenKeyframe(FK_Head_Ctrl.Off + '.v', cd=IK_FK_BlendCtrl.C + '.ty')
282 | cmds.setDrivenKeyframe(IK_Head_Ctrl.Off + '.v', cd=IK_FK_BlendCtrl.C + '.ty')
283 |
284 | cmds.setAttr(IK_FK_BlendCtrl.C + '.ty', 1)
285 | cmds.setAttr(FK_Neck_CtrlGrp_List[0] + '.v', 0)
286 | cmds.setAttr(FK_Head_Ctrl.Off + '.v', 0)
287 | cmds.setAttr(IK_Head_Ctrl.Off + '.v', 1)
288 |
289 | cmds.setDrivenKeyframe(FK_Neck_CtrlGrp_List[0] + '.v', cd=IK_FK_BlendCtrl.C + '.ty')
290 | cmds.setDrivenKeyframe(FK_Head_Ctrl.Off + '.v', cd=IK_FK_BlendCtrl.C + '.ty')
291 | cmds.setDrivenKeyframe(IK_Head_Ctrl.Off + '.v', cd=IK_FK_BlendCtrl.C + '.ty')
292 |
293 | neckLoc = cmds.spaceLocator(n=prefix + 'Neck_Loc')
294 |
295 | if Neck_Parent:
296 | cmds.parentConstraint(Neck_Parent, neckLoc, mo=0)
297 |
298 | cmds.parent(FK_Neck_CtrlGrp_List[0], neckLoc)
299 | cmds.parent(IK_Head_Ctrl.Off, neckLoc)
300 |
301 | # fk_headLocal and fk_headWorld
302 | cmds.parent(fk_headLocal, FK_Neck_Ctrl_List[-1])
303 | cmds.parent(fk_headWorld, rigModule.topGrp)
304 | # ik_headLocal and ik_headWorld
305 | cmds.parent(ik_headLocal, neckLoc)
306 | cmds.parent(ik_headWorld, rigModule.topGrp)
307 |
308 | # ik parts
309 | cmds.parent(IK_Part_List[0], rigModule.dontTouchGrp)
310 | cmds.parent(IK_Part_List[-1], rigModule.dontTouchGrp)
311 |
312 | # blend ctrl
313 | cmds.pointConstraint(blendCtrl_Pos, IK_FK_BlendCtrl.Off, mo=0)
314 | blendCtrl_Pos_Shape = cmds.listRelatives(blendCtrl_Pos, s=1)
315 | cmds.setAttr(blendCtrl_Pos_Shape[0] + '.localScaleX', 0)
316 | cmds.setAttr(blendCtrl_Pos_Shape[0] + '.localScaleY', 0)
317 | cmds.setAttr(blendCtrl_Pos_Shape[0] + '.localScaleZ', 0)
318 | cmds.setAttr(blendCtrl_Pos_Shape[0] + '.template', 1)
319 | headBlendLoc = cmds.spaceLocator(n=prefix + rigPartName + '_Blend_Loc')
320 | headBlendLoc_Shape = cmds.listRelatives(headBlendLoc, s=1)
321 | cmds.setAttr(headBlendLoc_Shape[0] + '.localScaleX', 0)
322 | cmds.setAttr(headBlendLoc_Shape[0] + '.localScaleY', 0)
323 | cmds.setAttr(headBlendLoc_Shape[0] + '.localScaleZ', 0)
324 | cmds.setAttr(headBlendLoc_Shape[0] + '.template', 1)
325 | cmds.pointConstraint(neckJoints[-2], headBlendLoc, mo=0)
326 | cmds.parent(blendCtrl_Pos, headBlendLoc)
327 | cmds.parent(IK_FK_BlendCtrl.Off, rigModule.topGrp)
328 | cmds.parent(headBlendLoc, rigModule.topGrp)
329 |
330 | # clean rigModule
331 | cmds.parent(FK_Head_Ctrl.Off, rigModule.topGrp)
332 | cmds.parent(neckLoc, rigModule.topGrp)
333 |
334 | # add attr
335 | for joint in neckJoints[:-1]:
336 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
337 | cmds.addAttr(joint, ln='slaveJoint', at='message')
338 |
339 | if not cmds.attributeQuery('rigModule', node=joint, exists=1):
340 | cmds.addAttr(joint, ln='rigModule', at='message')
341 |
342 | # connect attr
343 | for joint in neckJoints[:-1]:
344 | if cmds.attributeQuery('rigModule', node=joint, exists=1):
345 | cmds.connectAttr(rigModule.topGrp + '.' + prefix + rigPartName + '_Jnt',
346 | joint + '.rigModule', f=1)
347 |
348 | cmds.select(cl=1)
349 |
350 | return rigModule
351 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/rigLib/rig/IK_FK_HumanArm.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | from ..base import module
4 | from ..base import control
5 |
6 | from .. utils import name
7 | from .. utils import IK_FK_Switch
8 |
9 | reload(module)
10 | reload(control)
11 | reload(name)
12 | reload(IK_FK_Switch)
13 |
14 |
15 | def build(armJoints,
16 | prefix='L_',
17 | rigScale=1.0,
18 | FK_Parent='',
19 | switchCtrlPos='',
20 | baseRig=None):
21 | """
22 | Build the IK_FK_Arm rig.
23 | :param armJoints: list(str), armJoints list, [L_clavical, L_shoulder, L_elbow, L_wrist]
24 | :param prefix: str, prefix of the rig
25 | :param rigScale: float, rig scale of the IK_FK_Arm rig module.
26 | :param FK_Parent: str, the joint which armJoints[0] connects to.
27 | :param switchCtrlPos: str, position of the IK_FK_Blend_Ctrl position.
28 | :param baseRig: baseRig: str, base atttach of the rig. Base Class instance is used.
29 | :return: None
30 | """
31 |
32 | rigPartName = 'Arm'
33 |
34 | rigModule = module.Module(prefix=prefix,
35 | rigPartName=rigPartName,
36 | baseObject=baseRig)
37 |
38 | # create FK joints chain
39 | fk_preParent = armJoints[0]
40 | fk_Joint_List = []
41 | for i in xrange(len(armJoints)-1):
42 | newJnt = cmds.joint(n='FK_' + armJoints[i+1])
43 | cmds.delete(cmds.parentConstraint(armJoints[i+1], newJnt, mo=0))
44 | cmds.makeIdentity(newJnt, apply=1, t=1, r=1, s=1)
45 | cmds.parent(newJnt, fk_preParent)
46 | fk_Joint_List.append(newJnt)
47 | fk_preParent = newJnt
48 | cmds.select(cl=1)
49 | cmds.setAttr(fk_Joint_List[0] + '.v', 0)
50 |
51 | # create IK joints chain
52 | ik_preParent = armJoints[0]
53 | ik_Joint_List = []
54 | for i in xrange(len(armJoints)-1):
55 | newJnt = cmds.joint(n='IK_' + armJoints[i+1])
56 | cmds.delete(cmds.parentConstraint(armJoints[i+1], newJnt, mo=0))
57 | cmds.makeIdentity(newJnt, apply=1, t=1, r=1, s=1)
58 | cmds.parent(newJnt, ik_preParent)
59 | ik_Joint_List.append(newJnt)
60 | ik_preParent = newJnt
61 | cmds.select(cl=1)
62 |
63 | cmds.setAttr(ik_Joint_List[0] + '.v', 0)
64 |
65 | cmds.select(cl=1)
66 |
67 | ##############
68 | # Arm FK Rig #
69 | ##############
70 | FK_Arm_Ctrl_List = []
71 | FK_Arm_CtrlGrp_List = []
72 | for i in xrange(len(fk_Joint_List)):
73 | FK_Arm_Ctrl = control.Control(prefix=prefix + 'FK_',
74 | rigPartName=name.removePrefix(armJoints[i+1]),
75 | scale=rigScale*3.0,
76 | translateTo=fk_Joint_List[i],
77 | rotateTo=fk_Joint_List[i],
78 | shape='cubeOnBase',
79 | axis='x',
80 | lockChannels=['t', 's', 'v'])
81 | cmds.pointConstraint(FK_Arm_Ctrl.C, fk_Joint_List[i], mo=0)
82 | cmds.orientConstraint(FK_Arm_Ctrl.C, fk_Joint_List[i], mo=0)
83 |
84 | FK_Arm_Ctrl_List.append(FK_Arm_Ctrl.C)
85 | FK_Arm_CtrlGrp_List.append(FK_Arm_Ctrl.Off)
86 | cmds.select(cl=1)
87 |
88 | # lock the .rx and ry attribute of elbowCtrl
89 | # cmds.setAttr(FK_Arm_Ctrl_List[1] + '.rx', l=1, k=0)
90 | # cmds.setAttr(FK_Arm_Ctrl_List[1] + '.ry', l=1, k=0)
91 |
92 | # parent the CtrlGrps to the proper places
93 | for i in xrange(len(FK_Arm_Ctrl_List)-1):
94 | cmds.parent(FK_Arm_CtrlGrp_List[i+1], FK_Arm_Ctrl_List[i])
95 |
96 | # clavical Rig
97 | clavical_Ctrl = control.Control(prefix=prefix,
98 | rigPartName=name.removePrefix(armJoints[0]),
99 | scale=rigScale*3.0,
100 | translateTo=armJoints[0],
101 | rotateTo=armJoints[0],
102 | shape='rotationControl',
103 | axis='x',
104 | lockChannels=['t', 's', 'v'])
105 |
106 | cmds.orientConstraint(clavical_Ctrl.C, armJoints[0], mo=0)
107 |
108 | # Clavical local2World
109 | cmds.addAttr(clavical_Ctrl.C, ln='Local2World', at="float", min=0, max=1, dv=0, k=1)
110 |
111 | clavical_Local = cmds.spaceLocator(n=armJoints[0] + '_Local')
112 | clavical_Local_Shape = cmds.listRelatives(clavical_Local, s=1)
113 | cmds.setAttr(clavical_Local_Shape[0] + '.localScaleX', 0)
114 | cmds.setAttr(clavical_Local_Shape[0] + '.localScaleY', 0)
115 | cmds.setAttr(clavical_Local_Shape[0] + '.localScaleZ', 0)
116 | cmds.setAttr(clavical_Local_Shape[0] + '.template', 1)
117 |
118 | clavical_World = cmds.spaceLocator(n=armJoints[0] + '_World')
119 | clavical_World_Shape = cmds.listRelatives(clavical_World, s=1)
120 | cmds.setAttr(clavical_World_Shape[0] + '.localScaleX', 0)
121 | cmds.setAttr(clavical_World_Shape[0] + '.localScaleY', 0)
122 | cmds.setAttr(clavical_World_Shape[0] + '.localScaleZ', 0)
123 | cmds.setAttr(clavical_World_Shape[0] + '.template', 1)
124 |
125 | cmds.delete(cmds.parentConstraint(FK_Arm_Ctrl_List[0], clavical_Local, mo=0))
126 | cmds.delete(cmds.parentConstraint(FK_Arm_Ctrl_List[0], clavical_World, mo=0))
127 |
128 | cmds.pointConstraint(clavical_Local, FK_Arm_CtrlGrp_List[0], mo=0)
129 | clavical_OrientConstraint = cmds.orientConstraint(clavical_Local, clavical_World, FK_Arm_CtrlGrp_List[0], mo=0)
130 |
131 | cmds.setAttr(clavical_Ctrl.C + '.Local2World', 0)
132 | cmds.setAttr(clavical_OrientConstraint[0] + '.' + clavical_Local[0] + 'W0', 1)
133 | cmds.setAttr(clavical_OrientConstraint[0] + '.' + clavical_World[0] + 'W1', 0)
134 |
135 | cmds.setDrivenKeyframe(clavical_OrientConstraint[0] + '.' + clavical_Local[0] + 'W0',
136 | cd=clavical_Ctrl.C + '.Local2World')
137 | cmds.setDrivenKeyframe(clavical_OrientConstraint[0] + '.' + clavical_World[0] + 'W1',
138 | cd=clavical_Ctrl.C + '.Local2World')
139 |
140 | cmds.setAttr(clavical_Ctrl.C + '.Local2World', 1)
141 | cmds.setAttr(clavical_OrientConstraint[0] + '.' + clavical_Local[0] + 'W0', 0)
142 | cmds.setAttr(clavical_OrientConstraint[0] + '.' + clavical_World[0] + 'W1', 1)
143 |
144 | cmds.setDrivenKeyframe(clavical_OrientConstraint[0] + '.' + clavical_Local[0] + 'W0',
145 | cd=clavical_Ctrl.C + '.Local2World')
146 | cmds.setDrivenKeyframe(clavical_OrientConstraint[0] + '.' + clavical_World[0] + 'W1',
147 | cd=clavical_Ctrl.C + '.Local2World')
148 |
149 | cmds.parent(clavical_Local, armJoints[0])
150 | cmds.parent(clavical_World, rigModule.topGrp)
151 |
152 | ##############
153 | # Arm IK Rig #
154 | ##############
155 | IK_Arm_Ctrl = control.Control(prefix=prefix + 'IK_',
156 | rigPartName=rigPartName,
157 | scale=rigScale*3,
158 | translateTo=ik_Joint_List[-1],
159 | rotateTo=ik_Joint_List[-1],
160 | shape='circle')
161 |
162 | cmds.orientConstraint(IK_Arm_Ctrl.C, ik_Joint_List[-1], mo=0)
163 |
164 | IK_Arm_PV_Ctrl = control.Control(prefix=prefix + 'IK_',
165 | rigPartName=rigPartName + '_PV',
166 | scale=rigScale*3,
167 | translateTo=ik_Joint_List[1],
168 | shape='diamond',
169 | lockChannels=['r', 's', 'v'])
170 |
171 | ik_Part_List = cmds.ikHandle(n=prefix + rigPartName + '_IK', sj=ik_Joint_List[0],
172 | ee=ik_Joint_List[-1], sol='ikRPsolver')
173 |
174 | cmds.parent(ik_Part_List[0], IK_Arm_Ctrl.C)
175 | cmds.setAttr(ik_Part_List[0] + '.v', 0)
176 | cmds.poleVectorConstraint(IK_Arm_PV_Ctrl.C, ik_Part_List[0])
177 |
178 | ###############
179 | # FK Hand Rig #
180 | ###############
181 |
182 | # get finger joint list
183 | finger_Start_Joints_List = cmds.listRelatives(armJoints[-1], p=0, children=1, s=0, type='joint')
184 |
185 | finger_Joints_Dic = {}
186 | clean_Finger_Joints_Dic = {}
187 | for i in xrange(len(finger_Start_Joints_List)):
188 | finger_Joints_Dic[('Finger_' + str(i))] = cmds.listRelatives(finger_Start_Joints_List[i],
189 | p=0, allDescendents=1, s=0, type='joint')
190 | finger_Joints_Dic[('Finger_' + str(i))].append(finger_Start_Joints_List[i])
191 | # remove the end joint
192 | finger_Joints_Dic[('Finger_' + str(i))].reverse()
193 | clean_Finger_Joints_Dic[('Finger_' + str(i))] = finger_Joints_Dic[('Finger_' + str(i))][:-1]
194 |
195 | # create FK Ctrl
196 | finger_FK_Ctrl_Dic = {}
197 | finger_FK_CtrlGrp_Dic = {}
198 | for key in clean_Finger_Joints_Dic:
199 | finger_FK_Ctrl_Dic[key] = []
200 | finger_FK_CtrlGrp_Dic[key] = []
201 | for i in xrange(len(clean_Finger_Joints_Dic[key])):
202 | cleanRigPartName = name.removePrefix(name.removeSuffix(clean_Finger_Joints_Dic[key][i]))
203 | FK_Finger_Ctrl = control.Control(prefix=prefix + 'FK_',
204 | rigPartName=(cleanRigPartName + '_' + str(i)),
205 | scale=rigScale,
206 | translateTo=clean_Finger_Joints_Dic[key][i],
207 | rotateTo=clean_Finger_Joints_Dic[key][i],
208 | shape='circleZ',
209 | lockChannels=['t', 's', 'v']
210 | )
211 | cmds.pointConstraint(FK_Finger_Ctrl.C, clean_Finger_Joints_Dic[key][i], mo=0)
212 | cmds.orientConstraint(FK_Finger_Ctrl.C, clean_Finger_Joints_Dic[key][i], mo=0)
213 |
214 | finger_FK_Ctrl_Dic[key].append(FK_Finger_Ctrl.C)
215 | finger_FK_CtrlGrp_Dic[key].append(FK_Finger_Ctrl.Off)
216 |
217 | # clean the hierarchy
218 | for key in finger_FK_CtrlGrp_Dic:
219 | for i in xrange(len(finger_FK_CtrlGrp_Dic[key])-1):
220 | cmds.parent(finger_FK_CtrlGrp_Dic[key][i+1], finger_FK_Ctrl_Dic[key][i])
221 |
222 | # use locator as grp to control the handCtrl
223 | hand_Loc = cmds.spaceLocator(n=prefix + 'Wrist_Grp_Loc')
224 | hand_Loc_Shape = cmds.listRelatives(hand_Loc, s=1)
225 | cmds.setAttr(hand_Loc_Shape[0] + '.localScaleX', 0)
226 | cmds.setAttr(hand_Loc_Shape[0] + '.localScaleY', 0)
227 | cmds.setAttr(hand_Loc_Shape[0] + '.localScaleZ', 0)
228 |
229 | cmds.parentConstraint(armJoints[-1], hand_Loc, mo=0)
230 |
231 | for key in finger_FK_CtrlGrp_Dic:
232 | cmds.parent(finger_FK_CtrlGrp_Dic[key][0], hand_Loc)
233 |
234 | cmds.parent(hand_Loc, rigModule.topGrp)
235 |
236 | ###############
237 | # FK IK Blend #
238 | ###############
239 |
240 | IK_FK_Blend_Ctrl = control.Control(prefix=prefix,
241 | rigPartName=rigPartName + '_Blend',
242 | scale=rigScale * 3,
243 | translateTo=switchCtrlPos,
244 | shape='unitSliderControl',
245 | lockChannels=['tx', 'tz', 'r', 's', 'v'])
246 | # add enum attr for IK_FK seamless switch
247 | cmds.addAttr(IK_FK_Blend_Ctrl.C, ln='Mode', at='enum', en='IK:FK', k=1)
248 |
249 | cmds.rotate(0, 0, -90, IK_FK_Blend_Ctrl.Off, relative=1, objectSpace=1)
250 |
251 | for i in xrange(len(fk_Joint_List)):
252 | # create blendColors node
253 | blendNode = cmds.createNode('blendColors')
254 | # IK
255 | cmds.connectAttr(ik_Joint_List[i] + '.r', blendNode + '.color1', f=1)
256 | # FK
257 | cmds.connectAttr(fk_Joint_List[i] + '.r', blendNode + '.color2', f=1)
258 | # Skin
259 | cmds.connectAttr(blendNode + '.output', armJoints[i+1] + '.r', f=1)
260 | # blendNode
261 | cmds.connectAttr(IK_FK_Blend_Ctrl.C + '.ty', blendNode + '.blender')
262 |
263 | # visibility blend
264 | cmds.setAttr(IK_FK_Blend_Ctrl.C + '.ty', 0)
265 | cmds.setAttr(FK_Arm_CtrlGrp_List[0] + '.v', 1)
266 | cmds.setAttr(IK_Arm_Ctrl.Off + '.v', 0)
267 | cmds.setAttr(IK_Arm_PV_Ctrl.Off + '.v', 0)
268 |
269 | cmds.setDrivenKeyframe(FK_Arm_CtrlGrp_List[0] + '.v', cd=IK_FK_Blend_Ctrl.C + '.ty')
270 | cmds.setDrivenKeyframe(IK_Arm_Ctrl.Off + '.v', cd=IK_FK_Blend_Ctrl.C + '.ty')
271 | cmds.setDrivenKeyframe(IK_Arm_PV_Ctrl.Off + '.v', cd=IK_FK_Blend_Ctrl.C + '.ty')
272 |
273 | cmds.setAttr(IK_FK_Blend_Ctrl.C + '.ty', 1)
274 | cmds.setAttr(FK_Arm_CtrlGrp_List[0] + '.v', 0)
275 | cmds.setAttr(IK_Arm_Ctrl.Off + '.v', 1)
276 | cmds.setAttr(IK_Arm_PV_Ctrl.Off + '.v', 1)
277 |
278 | cmds.setDrivenKeyframe(FK_Arm_CtrlGrp_List[0] + '.v', cd=IK_FK_Blend_Ctrl.C + '.ty')
279 | cmds.setDrivenKeyframe(IK_Arm_Ctrl.Off + '.v', cd=IK_FK_Blend_Ctrl.C + '.ty')
280 | cmds.setDrivenKeyframe(IK_Arm_PV_Ctrl.Off + '.v', cd=IK_FK_Blend_Ctrl.C + '.ty')
281 |
282 | cmds.pointConstraint(switchCtrlPos, IK_FK_Blend_Ctrl.Off, mo=0)
283 | switchCtrlPos_Shape = cmds.listRelatives(switchCtrlPos, s=1)
284 | cmds.setAttr(switchCtrlPos_Shape[0] + '.localScaleX', 0)
285 | cmds.setAttr(switchCtrlPos_Shape[0] + '.localScaleY', 0)
286 | cmds.setAttr(switchCtrlPos_Shape[0] + '.localScaleZ', 0)
287 | cmds.setAttr(switchCtrlPos_Shape[0] + '.template', 1)
288 | switchCtrlLoc = cmds.spaceLocator(n=prefix + rigPartName + 'BlendCtrl_Loc')
289 | switchCtrlLoc_Shape = cmds.listRelatives(switchCtrlLoc, s=1)
290 | cmds.setAttr(switchCtrlLoc_Shape[0] + '.localScaleX', 0)
291 | cmds.setAttr(switchCtrlLoc_Shape[0] + '.localScaleY', 0)
292 | cmds.setAttr(switchCtrlLoc_Shape[0] + '.localScaleZ', 0)
293 | cmds.setAttr(switchCtrlLoc_Shape[0] + '.template', 1)
294 |
295 | cmds.pointConstraint(armJoints[-1], switchCtrlLoc, mo=0)
296 | cmds.parent(switchCtrlPos, switchCtrlLoc)
297 |
298 | # add attr
299 | for joint in armJoints:
300 | if not cmds.attributeQuery('rigModule', node=joint, exists=1):
301 | cmds.addAttr(joint, ln='rigModule', at='message')
302 |
303 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
304 | cmds.addAttr(joint, ln='slaveJoint', at='message')
305 |
306 | for key in clean_Finger_Joints_Dic.keys():
307 | for joint in clean_Finger_Joints_Dic[key]:
308 | if not cmds.attributeQuery(prefix + rigPartName + '_Jnt', node=joint, exists=1):
309 | cmds.addAttr(joint, ln=prefix + rigPartName + '_Jnt', at='message')
310 |
311 | if not cmds.attributeQuery('slaveJoint', node=joint, exists=1):
312 | cmds.addAttr(joint, ln='slaveJoint', at='message')
313 |
314 | # connect attr
315 | for joint in armJoints:
316 | if cmds.attributeQuery('rigModule', node=joint, exists=1):
317 | cmds.connectAttr(rigModule.topGrp + '.' + prefix + rigPartName + '_Jnt',
318 | joint + '.rigModule', f=1)
319 |
320 | for key in clean_Finger_Joints_Dic.keys():
321 | for joint in clean_Finger_Joints_Dic[key]:
322 | if cmds.attributeQuery('rigModule', node=joint, exists=1):
323 | cmds.connectAttr(rigModule.topGrp + '.' + prefix + rigPartName + '_Jnt',
324 | joint + '.rigModule', f=1)
325 |
326 | # final cleaning
327 | cmds.parent(FK_Arm_CtrlGrp_List[0], clavical_Ctrl.C)
328 |
329 | if FK_Parent:
330 | FK_Loc = cmds.spaceLocator(n=prefix + rigPartName + '_Loc')
331 | FK_LocShape = cmds.listRelatives(FK_Loc, s=1)
332 | cmds.setAttr(FK_LocShape[0] + '.localScaleX', 0)
333 | cmds.setAttr(FK_LocShape[0] + '.localScaleY', 0)
334 | cmds.setAttr(FK_LocShape[0] + '.localScaleZ', 0)
335 | cmds.parentConstraint(FK_Parent, FK_Loc, mo=0)
336 | cmds.parent(clavical_Ctrl.Off, FK_Loc)
337 | cmds.parent(FK_Loc, rigModule.topGrp)
338 | else:
339 | cmds.warning('FK_Parent is None')
340 | cmds.parent(clavical_Ctrl.Off, rigModule.topGrp)
341 |
342 | cmds.parent(IK_Arm_PV_Ctrl.Off, rigModule.topGrp)
343 | cmds.parent(IK_Arm_Ctrl.Off, rigModule.topGrp)
344 | cmds.parent(switchCtrlLoc, rigModule.topGrp)
345 | cmds.parent(IK_FK_Blend_Ctrl.Off, rigModule.topGrp)
346 |
347 | cmds.select(cl=1)
348 |
349 | # IK_FK_seamless Switch by scriptJob and scriptNode
350 | IK_FK_Switch.IK_FK_Switch(prefix=prefix,
351 | switchCtrl=IK_FK_Blend_Ctrl.C,
352 | pvCtrl=IK_Arm_PV_Ctrl.C,
353 | ikCtrl=IK_Arm_Ctrl.C,
354 | skinJoints=armJoints[1:],
355 | fkCtrlList=FK_Arm_Ctrl_List)
356 |
357 | cmds.select(cl=1)
358 |
359 | return rigModule
360 |
--------------------------------------------------------------------------------
/CustomProceduralRiggingTool/CustomProceduralRigTool/skinLib/skinLib.py:
--------------------------------------------------------------------------------
1 | import os
2 | import cPickle as pickle
3 | import maya.cmds as cmds
4 | import maya.OpenMaya as openmaya
5 | import maya.OpenMayaUI as openmayaui
6 | import maya.OpenMayaAnim as openmayaanim
7 | from functools import partial
8 |
9 |
10 | from PySide2 import QtGui, QtWidgets, QtCore
11 | from shiboken2 import wrapInstance
12 |
13 |
14 | def show():
15 | """
16 | Show Export and Import dialog UI
17 | :return:
18 | """
19 | dialog = SkinIODialog(getMayaWindow())
20 | dialog.show()
21 |
22 |
23 | def getMayaWindow():
24 | """
25 | Get the mayaMainWindow as parent
26 | :return: mayaMainWindow Ptr
27 | """
28 | ptr = openmayaui.MQtUtil.mainWindow()
29 | return wrapInstance(long(ptr), QtWidgets.QMainWindow)
30 |
31 |
32 | def getShape(node, intermediate=False):
33 | """
34 | Get the shape from specified node.
35 |
36 | :param node: node Name of a transform or shape node.
37 | :param intermediate: intermediate True to get the intermediate shape, False to get the visible shape
38 | :return: the name of the desired shape node
39 | """
40 | if cmds.nodeType(node) == 'transform':
41 | shapes = cmds.listRelatives(node, shapes=1, path=1)
42 |
43 | # from transform node to get the shape node
44 | if not shapes:
45 | shapes = []
46 | for shape in shapes:
47 | isIntermediate = cmds.getAttr('%s.intermediateObject' % shape)
48 | # Sometimes there are left over intermediate shapes that are not used to(the duplicated deformed shape)
49 | # check the connections to make sure we get the one that is used
50 | # return intermediate shape which has incoming objects
51 | if intermediate and isIntermediate and cmds.listConnections(shape, source=0, destination=1):
52 | return shape
53 |
54 | # return visible shape
55 | elif not intermediate and not isIntermediate:
56 | return shape
57 |
58 | if shapes:
59 | return shapes[0]
60 | # return the shape which just is a Shape Node
61 | elif cmds.nodeType(node) in ['mesh', 'nurbsCurve', 'nurbsSurface']:
62 | return node
63 |
64 | return None
65 |
66 |
67 | class SkinCluster(object):
68 | # global variable extension
69 | kFileExtension = '.skin'
70 |
71 | @classmethod
72 | def export(cls, filePath=None, shape=None):
73 | skin = SkinCluster(shape)
74 | skin.exportSkin(filePath)
75 |
76 | @classmethod
77 | def createAndImport(cls, filePath=None, shape=None):
78 | """
79 | Create a skinCluster on the specified shape if one does not already exist
80 | and then import the weight data.
81 | :param filePath: filePath of the skinWeights
82 | :param shape: mesh shape which skinCluster deforms
83 | :return:
84 | """
85 |
86 | if not shape:
87 | try:
88 | shape = cmds.ls(sl=1)[0]
89 |
90 | except:
91 | raise RuntimeError('No shape selected')
92 |
93 | if filePath == None:
94 | startDir = cmds.workspace(q=1, rootDirectory=1)
95 | filePath = cmds.fileDialog2(dialogStyle=2, fileMode=1, startingDirectory=startDir,
96 | fileFilter='Skin Files (*%s)' % SkinCluster.kFileExtension)
97 |
98 | if not filePath:
99 | return
100 | if not isinstance(filePath, basestring):
101 | filePath = filePath[0]
102 |
103 | # Read the data from the file
104 | fh = open(filePath, 'rb')
105 | data = pickle.load(fh)
106 | fh.close()
107 |
108 | # Make sure the vertex count is the same
109 | meshVertices = cmds.polyEvaluate(shape, vertex=1)
110 |
111 | importedVertices = len(data['blendWeights'])
112 | if meshVertices != importedVertices:
113 | raise RuntimeError('Vertex counts do not match. %d != %d' % (meshVertices, importedVertices))
114 |
115 |
116 | # check if the shape already has a skinCluster
117 | if SkinCluster.getSkinCluster(shape):
118 | skinCluster = SkinCluster(shape)
119 | else:
120 | # create a new skinCluster
121 | joints = data['weights'].keys()
122 |
123 | # Make sure all the joints exist
124 |
125 | unusedImports = []
126 | # Create a set for get which joint in the scene doesn't have weights
127 | noMatch = set([SkinCluster.removeNamespaceFromString(x) for x in cmds.ls(type='joint')])
128 |
129 | for j in joints:
130 | if j in noMatch:
131 | noMatch.remove(j)
132 | else:
133 | unusedImports.append(j)
134 |
135 | # Remapping the joints
136 | # if there were unmapped influences ask the user to map them
137 | if unusedImports and noMatch:
138 |
139 | mappingDialog = WeightRemapDialog(getMayaWindow())
140 | mappingDialog.setInfluences(unusedImports, noMatch)
141 | mappingDialog.exec_()
142 |
143 | for src, dst in mappingDialog.mapping.items():
144 | # swap the mapping
145 | data['weights'][dst] = data['weights'][src]
146 | del data['weights'][src]
147 |
148 | # Create the skinCluster with post normalization so setting the weights does not
149 | # normalize all weights
150 | joints = data['weights'].keys()
151 |
152 | skinCluster = cmds.skinCluster(joints, shape, tsb=1, nw=2, n=data['name'])
153 | skinCluster = SkinCluster(shape)
154 |
155 | skinCluster.setData(data)
156 | print "Imported %s" % filePath
157 |
158 | @classmethod
159 | def getSkinCluster(cls, shape):
160 | """
161 | Get the skinCluster node attached to the specified shape.
162 | :param shape: Shape node name
163 | :return: The attached skinCluster name or None if no skinCluster is attached
164 | """
165 | shape = getShape(shape)
166 | history = cmds.listHistory(shape, pruneDagObjects=1, interestLevel=2)
167 |
168 | if not history:
169 | return None
170 | skins = [x for x in history if cmds.nodeType(x) == 'skinCluster']
171 |
172 | if skins:
173 | return skins[0]
174 | return None
175 |
176 | @classmethod
177 | def removeNamespaceFromString(cls, influenceName):
178 | """
179 | Remove namespaces from a string
180 | CHANGES NAMESPACE: joint1 | NAMESAPCE:joint2 -> joint1 | joint2
181 | :param influenceName: string, name with a namespace
182 | :return: string ,name without a namespace
183 | """
184 | tokens = influenceName.split('|')
185 | result = ''
186 |
187 | for i, tokens in enumerate(tokens):
188 | if i > 0:
189 | result += '|'
190 |
191 | result += tokens.split(':')[-1]
192 |
193 | return result
194 |
195 | def __init__(self, shape=None):
196 | if not shape:
197 | try:
198 | shape = cmds.ls(sl=1)[0]
199 |
200 | except:
201 | raise RuntimeError('No shape selected')
202 |
203 | self.shape = getShape(shape)
204 | if not self.shape:
205 | raise RuntimeError('No shape connected to %s' % shape)
206 |
207 | # Get the skinCluster node attached to the shape
208 | self.node = SkinCluster.getSkinCluster(self.shape)
209 | if not self.node:
210 | raise ValueError('No skinCluster attached to %s' % self.shape)
211 |
212 | # Get the skinCluster MObject
213 | selectionList = openmaya.MSelectionList()
214 | selectionList.add(self.node)
215 | self.mobj = openmaya.MObject()
216 | selectionList.getDependNode(0, self.mobj)
217 | self.fn = openmayaanim.MFnSkinCluster(self.mobj)
218 | self.data = {'weights': {},
219 | 'blendWeights': [],
220 | 'name': self.node}
221 |
222 | def gatherData(self):
223 | """
224 | get and store the skinningMethod and normalizeWeights attributes in data dictionary
225 | :return: None
226 | """
227 | dagPath, components = self.__getGeometryComponents()
228 | self.gatherInfluenceWeights(dagPath, components)
229 | self.gatherBlendWeights(dagPath, components)
230 |
231 | for attr in ['skinningMethod', 'normalizeWeights']:
232 | self.data[attr] = cmds.getAttr('%s.%s' % (self.node, attr))
233 |
234 | def __getGeometryComponents(self):
235 | """
236 | get the dagPath of influence object(joint) and Geometry components(vertex)
237 | :return: dagPath, componnets
238 | """
239 | # get dagPath and member components of skined shape
240 | # the deformerSet pretty controls which vertex is deformed by the skinCluster
241 | # the deformerSet will allows us to pull out that components(vertex) mobject that we need
242 | fnSet = openmaya.MFnSet(self.fn.deformerSet())
243 | members = openmaya.MSelectionList()
244 | # the MSelectionList contains the vertex information in the deformerSet above
245 | fnSet.getMembers(members, False)
246 |
247 | dagPath = openmaya.MDagPath()
248 | components = openmaya.MObject()
249 |
250 | # dagPath: dagPath of influence objects(joint)
251 | # components: mesh components(vertex)
252 | members.getDagPath(0, dagPath, components)
253 |
254 | return dagPath, components
255 |
256 | def gatherInfluenceWeights(self, dagPath, components):
257 | """
258 | get and store the weights of each influence object for same ordered components(vertex) in data['weights'] dictionary
259 | :param dagPath:
260 | :param components: mesh components(vertex)
261 | :return: None
262 | """
263 | # Gathers all the influence weights
264 | weights = self.__getCurrentWeights(dagPath, components)
265 |
266 | influencePaths = openmaya.MDagPathArray()
267 | # influencePaths is the fullPath of the object(joint)
268 | numInfluences = self.fn.influenceObjects(influencePaths)
269 | # weight size = number of components(vertex) * number of influenceObjects(joints)
270 | numComponentsPerInfluence = weights.length() / numInfluences
271 |
272 | for ii in range(influencePaths.length()):
273 | influenceName = influencePaths[ii].partialPathName()
274 | # we want to store the weights by influence without the namespace so it is easier
275 | # to import if the namespace is different
276 | influenceNameWithoutNamespace = SkinCluster.removeNamespaceFromString(influenceName)
277 | # store the weight of each influence object(joint) for same ordered components(vertex)
278 | self.data['weights'][influenceNameWithoutNamespace] = [weights[jj * numInfluences + ii] for jj in range(numComponentsPerInfluence)]
279 |
280 | def gatherBlendWeights(self, dagPath, components):
281 | """
282 | Gather the BlendWeights
283 | :param dagPath: dagPath of influence objects(joint)
284 | :param components: mesh components(vertex)
285 | :return: None
286 | """
287 | weights = openmaya.MDoubleArray()
288 | self.fn.getBlendWeights(dagPath, components, weights)
289 | self.data['blendWeights'] = [weights[i] for i in range(weights.length())]
290 |
291 | def __getCurrentWeights(self, dagPath, components):
292 | """
293 | Get the current weights array. Be careful about the weight array, it is a giant single array.
294 | The order of the weights array is dependent on the indices of the joint
295 | :param dagPath: path to object deformed by the skinCluster
296 | :param components: Components to return weight for, every single vertex in the mesh
297 | :return: Weights
298 | """
299 | weights = openmaya.MDoubleArray()
300 | util = openmaya.MScriptUtil()
301 |
302 | util.createFromInt(0)
303 |
304 | pUInt = util.asUintPtr()
305 | # Gets the skinCluster weights for ALL influenceObjects(joints) for the specified components of the object whose dagPath is specified.
306 | # More details see: https://download.autodesk.com/us/maya/2011help/API/class_m_fn_skin_cluster.html#82e83fc5ab653aa15c5431710b3ac86a
307 | self.fn.getWeights(dagPath, components, weights, pUInt)
308 | # weights is a giant single Double Array
309 | # size = number of components(vertex) * number of influenceObjects(joints)
310 | return weights
311 |
312 | def exportSkin(self, filePath=None):
313 | """
314 | Export the skinCluster data to disk
315 | :param filePath: File Path
316 | :return:
317 | """
318 | if filePath == None:
319 | startDir = cmds.workspace(q=1, rootDirectory=1)
320 | filePath = cmds.fileDialog2(dialogStyle=2, fileMode=0, startingDirectory=startDir,
321 | fileFilter='Skin Files(*%s)' % SkinCluster.kFileExtension)
322 |
323 | if not filePath:
324 | return
325 |
326 | filePath = filePath[0]
327 |
328 | if not filePath.endswith(SkinCluster.kFileExtension):
329 | filePath += SkinCluster.kFileExtension
330 |
331 | self.gatherData()
332 |
333 | fh = open(filePath, 'wb')
334 | pickle.dump(self.data, fh, pickle.HIGHEST_PROTOCOL)
335 |
336 | fh.close()
337 | print "Exported skinCluster (%d influences, %d vertices) %s" % (len(self.data['weights'].keys()), len(self.data['blendWeights']), filePath)
338 |
339 | def setData(self, data):
340 | """
341 | Sets the data and stores it in the Maya skinCluster node.
342 | :return:
343 | """
344 | self.data = data
345 | dagPath, components = self.__getGeometryComponents()
346 | self.setInfluenceWeights(dagPath, components)
347 | self.setBlendWeights(dagPath, components)
348 |
349 | for attr in ['skinningMethod', 'normalizeWeights']:
350 | cmds.setAttr('%s.%s' % (self.node, attr), self.data[attr])
351 |
352 | def setInfluenceWeights(self, dagPath, components):
353 | """
354 |
355 | :param dagPath:
356 | :param components:
357 | :return:
358 | """
359 | # get the existing weights and fill in the new weights
360 | weights = self.__getCurrentWeights(dagPath, components)
361 | influencePaths = openmaya.MDagPathArray()
362 | numInfluences = self.fn.influenceObjects(influencePaths)
363 | numComponentsPerInfluence = weights.length() / numInfluences
364 |
365 | # Keep track of which imported influences aren't used
366 | unusedImports = []
367 | # Keep track of which existing influences don't get anything imported
368 | noMatch = [influencePaths[ii].partialPathName() for ii in xrange(influencePaths.length())]
369 |
370 | for importedInfluence, importedWeights in self.data['weights'].items():
371 | for inf_count in xrange(influencePaths.length()):
372 | # partialPathName used to return exclusive partial path name of the object
373 | influenceName = influencePaths[inf_count].partialPathName()
374 | influenceWithoutNamespace = SkinCluster.removeNamespaceFromString(influenceName)
375 |
376 | if influenceWithoutNamespace == importedInfluence:
377 | # Store the imported weights into the MDoubeArray
378 | for jj in xrange(numComponentsPerInfluence):
379 | weights.set(importedWeights[jj], jj * numInfluences + inf_count)
380 |
381 | noMatch.remove(influenceName)
382 | break
383 | else:
384 | unusedImports.append(importedInfluence)
385 |
386 | if unusedImports and noMatch:
387 | mappingDialog = WeightRemapDialog(getMayaWindow())
388 | mappingDialog.setInfluences(unusedImports, noMatch)
389 | mappingDialog.exec_()
390 | for src, dst in mappingDialog.mapping.items():
391 | for ii in range(influencePaths.length()):
392 | if influencePaths[ii].partialPathName() == dst:
393 | for jj in range(numComponentsPerInfluence):
394 | weights.set(self.data['weights'][src][jj], jj*numInfluences+ii)
395 | break
396 |
397 | influenceIndics = openmaya.MIntArray(numInfluences)
398 | for ii in range(numInfluences):
399 | influenceIndics.set(ii, ii)
400 | self.fn.setWeights(dagPath, components, influenceIndics, weights, False)
401 |
402 | def setBlendWeights(self, dagPath, components):
403 | """
404 | Set BlendWeights
405 | :param dagPath:
406 | :param components:
407 | :return:
408 | """
409 | blendWeights = openmaya.MDoubleArray(len(self.data['blendWeights']))
410 | for i, w in enumerate(self.data['blendWeights']):
411 | blendWeights.set(w, i)
412 |
413 | self.fn.setBlendWeights(dagPath, components, blendWeights)
414 |
415 |
416 | class WeightRemapDialog(QtWidgets.QDialog):
417 | def __init__(self, parent=None):
418 | super(WeightRemapDialog, self).__init__(parent)
419 |
420 | self.setWindowTitle('Remap Weights')
421 | self.setObjectName('remapWeightUI')
422 |
423 | self.setModal(True)
424 | self.resize(600, 400)
425 | self.mapping = {}
426 |
427 | self.mainVbox = QtWidgets.QVBoxLayout()
428 |
429 | self.setLayout(self.mainVbox)
430 |
431 | label = QtWidgets.QLabel('The following influences have no corresponding influence from the import file. '
432 | 'You can either remap the influences or skip them')
433 |
434 | label.setWordWrap(True)
435 |
436 | self.mainVbox.addWidget(label)
437 |
438 | self.HBox = QtWidgets.QHBoxLayout()
439 | self.mainVbox.addLayout(self.HBox)
440 |
441 |
442 | self.VBox = QtWidgets.QVBoxLayout()
443 | self.HBox.addLayout(self.VBox)
444 |
445 | self.VBox.addWidget(QtWidgets.QLabel('Unmapped influences'))
446 |
447 | self.existingInfluences = QtWidgets.QListWidget()
448 | self.VBox.addWidget(self.existingInfluences)
449 |
450 | vbox = QtWidgets.QVBoxLayout()
451 | self.HBox.addLayout(vbox)
452 | vbox.addWidget(QtWidgets.QLabel('Available imported influence'))
453 | self.scrollArea = QtWidgets.QScrollArea()
454 | self.widget = QtWidgets.QScrollArea()
455 | self.importedInfluenceLayout = QtWidgets.QVBoxLayout(self.widget)
456 | vbox.addWidget(self.widget)
457 |
458 | hbox = QtWidgets.QHBoxLayout()
459 | self.mainVbox.addLayout(hbox)
460 | hbox.addStretch()
461 | self.btn = QtWidgets.QPushButton('OK')
462 | self.btn.released.connect(self.accept)
463 | hbox.addWidget(self.btn)
464 |
465 | def setInfluences(self, importedInfluences, existingInfluences):
466 | infs = list(existingInfluences)
467 | infs.sort()
468 | self.existingInfluences.addItems(infs)
469 |
470 | width = 200
471 | for inf in importedInfluences:
472 | row = QtWidgets.QHBoxLayout()
473 | self.importedInfluenceLayout.addLayout(row)
474 |
475 | label = QtWidgets.QLabel(inf)
476 | row.addWidget(label)
477 |
478 | toggleBtn = QtWidgets.QPushButton('->')
479 | toggleBtn.setMaximumWidth(30)
480 | row.addWidget(toggleBtn)
481 |
482 | label = QtWidgets.QLabel('')
483 | label.setMaximumWidth(width)
484 | label.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
485 | row.addWidget(label)
486 |
487 | toggleBtn.released.connect(partial(self.setInfluencesMapping, src=inf, label=label))
488 |
489 | self.importedInfluenceLayout.addStretch()
490 |
491 |
492 | def setInfluencesMapping(self, src, label):
493 | selectedInfluence = self.existingInfluences.selectedItems()
494 |
495 | if not selectedInfluence:
496 | return
497 |
498 | dst = selectedInfluence[0].text()
499 |
500 | label.setText(dst)
501 |
502 | self.mapping[src] = dst
503 |
504 | index = self.existingInfluences.indexFromItem(selectedInfluence[0])
505 |
506 | item = self.existingInfluences.takeItem(index.row())
507 |
508 | del item
509 |
510 |
511 | class SkinIODialog(QtWidgets.QDialog):
512 |
513 | def __init__(self, parent=None):
514 | super(SkinIODialog, self).__init__(parent)
515 |
516 | self.setWindowTitle('Skin IO')
517 | self.setObjectName('skinioWidget')
518 | self.setModal(False)
519 | self.setFixedSize(200, 80)
520 |
521 | self.vbox = QtWidgets.QVBoxLayout()
522 | self.setLayout(self.vbox)
523 |
524 | self.exportBtn = QtWidgets.QPushButton("Export")
525 | self.vbox.addWidget(self.exportBtn)
526 | self.exportBtn.clicked.connect(SkinCluster.export)
527 |
528 | self.importBtn = QtWidgets.QPushButton("Import")
529 | self.vbox.addWidget(self.importBtn)
530 | self.importBtn.clicked.connect(SkinCluster.createAndImport)
531 |
--------------------------------------------------------------------------------