├── FoleyUtils
├── __init__.py
├── icons
│ ├── futil_ok.png
│ ├── futil_ask.png
│ ├── futil_cancle.png
│ ├── futil_error.png
│ └── futil_warning.png
├── ioTool.py
├── scriptTool.py
├── colorTool.py
├── mathTool.py
├── nameTool.py
└── publishTool.py
├── Plugcmds
├── __init__.py
├── DynControl
│ ├── __init__.py
│ ├── makeScriptNode.mel
│ ├── hairSystemConnection.txt
│ └── DynControlUI.ui
├── FixShape
│ ├── __init__.py
│ └── Data.json
├── HeadStreatch
│ └── __init__.py
├── IKFKSwitch
│ └── __init__.py
├── ReplaceUV
│ ├── __init__.py
│ ├── RemoveUVWasteNode.py
│ ├── replaceUV.ui
│ └── ReplaceUV.py
├── TransWeights
│ ├── __init__.py
│ ├── icons
│ │ ├── load.png
│ │ ├── export.png
│ │ └── import.png
│ ├── TransWeights.py
│ └── TransWeights.ui
├── addGroups
│ ├── __init__.py
│ ├── addGroups.py
│ └── addGroups.ui
├── inspectScene
│ ├── __init__.py
│ └── inspectScene.py
├── projectTool
│ ├── __init__.py
│ ├── icons
│ │ ├── folder.png
│ │ ├── map_pin.png
│ │ └── windowIcon.png
│ ├── ProjectTool_UI.ui
│ └── ProjectTool.py
├── weightsTool
│ └── __init__.py
├── AnimSceneReader
│ ├── __init__.py
│ └── icons
│ │ ├── fork.png
│ │ ├── light_on.png
│ │ ├── map_pin.png
│ │ ├── blank_folder.png
│ │ └── cloud_upload.png
├── ConvertControl
│ ├── __init__.py
│ ├── ControlParentData.json
│ ├── ControlVisbilityData.json
│ └── FaceControlBuilderUI.py
├── addTwistJoints
│ ├── __init__.py
│ └── warningDialog.ui
├── makeAttachJoints
│ ├── __init__.py
│ └── makeAttachJoints.py
├── CopyBlendShapeWeights
│ ├── __init__.py
│ └── icons
│ │ ├── arrow.png
│ │ └── refresh.png
├── MirrorClusterWeights
│ ├── __init__.py
│ └── MirrorClusterWeights.py
├── blendShapeWeightsTool
│ ├── __init__.py
│ └── blendShapeWeights.py
├── findCoincidentGeometry
│ ├── __init__.py
│ ├── findCoincidentGeometryUI.py
│ ├── findCoincidentGeometry.ui
│ └── findCoincidentGeometry.py
├── transSkinWeightsToCluster
│ ├── __init__.py
│ └── transWeights.py
├── old
│ ├── ClusterWeight.docx
│ ├── ClusterWeight.mel
│ ├── ControlColors.py
│ ├── ClusterWeight.py
│ └── nameTool.py
├── ControlSelecter
│ ├── icon
│ │ ├── IKFK.png
│ │ ├── SDP.png
│ │ ├── hip.png
│ │ ├── toe.png
│ │ ├── 未标题-1.psd
│ │ ├── Vector.png
│ │ ├── IKControl.png
│ │ ├── background_a.png
│ │ └── background_b.png
│ ├── TposeData.py
│ ├── __init__.py
│ └── ControlSelecterUIASSERT.qrc
├── ShapeBuilder
│ ├── __init__.py
│ └── cvShapeInverter.py
├── StreatchSacleToTranslate.py
├── addPalmBindJoint.py
├── quickSDKTool.py
├── ControlColors.py
├── Tpose.py
├── RenameJnts.py
├── ControlColor.py
├── latticeWeightsTool.py
├── saveDrivenKeys.py
├── mirrorFaceControlDrivenkeys.py
├── createControlSet.py
├── ChangeOBJpivot.py
├── SetDrivenKeysforToes.py
├── quickSetDrivenKey.py
├── BlendIKFKoutputs.py
├── mirrorCtlShp.py
├── makeRotateInfo.py
├── buildTargents.py
├── blendShapeWeights.ui
├── FixAnim.py
├── mirrorCtlShp.ui
├── mirrorSDK.py
├── blendShapeWeights.py
├── mirrorBlendShapeWeights.ui
└── quickSDKTool.ui
├── icons
├── help.png
├── bikini.png
├── brush.png
├── pencil.png
├── scissors.png
└── windowIcon.png
├── Snapshot
├── QQSnapShot.exe
├── BaiduSnapshot.exe
└── SogouSnapShot.exe
├── README.txt
└── .gitignore
/FoleyUtils/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/DynControl/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/FixShape/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/HeadStreatch/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/IKFKSwitch/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/ReplaceUV/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/TransWeights/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/addGroups/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/inspectScene/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/projectTool/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/weightsTool/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/AnimSceneReader/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/ConvertControl/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/addTwistJoints/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/makeAttachJoints/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/CopyBlendShapeWeights/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/MirrorClusterWeights/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/blendShapeWeightsTool/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/findCoincidentGeometry/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Plugcmds/transSkinWeightsToCluster/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/icons/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/icons/help.png
--------------------------------------------------------------------------------
/icons/bikini.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/icons/bikini.png
--------------------------------------------------------------------------------
/icons/brush.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/icons/brush.png
--------------------------------------------------------------------------------
/icons/pencil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/icons/pencil.png
--------------------------------------------------------------------------------
/icons/scissors.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/icons/scissors.png
--------------------------------------------------------------------------------
/icons/windowIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/icons/windowIcon.png
--------------------------------------------------------------------------------
/Snapshot/QQSnapShot.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Snapshot/QQSnapShot.exe
--------------------------------------------------------------------------------
/Snapshot/BaiduSnapshot.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Snapshot/BaiduSnapshot.exe
--------------------------------------------------------------------------------
/Snapshot/SogouSnapShot.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Snapshot/SogouSnapShot.exe
--------------------------------------------------------------------------------
/FoleyUtils/icons/futil_ok.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/FoleyUtils/icons/futil_ok.png
--------------------------------------------------------------------------------
/FoleyUtils/icons/futil_ask.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/FoleyUtils/icons/futil_ask.png
--------------------------------------------------------------------------------
/Plugcmds/old/ClusterWeight.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/old/ClusterWeight.docx
--------------------------------------------------------------------------------
/FoleyUtils/icons/futil_cancle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/FoleyUtils/icons/futil_cancle.png
--------------------------------------------------------------------------------
/FoleyUtils/icons/futil_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/FoleyUtils/icons/futil_error.png
--------------------------------------------------------------------------------
/FoleyUtils/icons/futil_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/FoleyUtils/icons/futil_warning.png
--------------------------------------------------------------------------------
/Plugcmds/TransWeights/icons/load.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/TransWeights/icons/load.png
--------------------------------------------------------------------------------
/Plugcmds/AnimSceneReader/icons/fork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/AnimSceneReader/icons/fork.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/IKFK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/IKFK.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/SDP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/SDP.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/hip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/hip.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/toe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/toe.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/未标题-1.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/未标题-1.psd
--------------------------------------------------------------------------------
/Plugcmds/TransWeights/icons/export.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/TransWeights/icons/export.png
--------------------------------------------------------------------------------
/Plugcmds/TransWeights/icons/import.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/TransWeights/icons/import.png
--------------------------------------------------------------------------------
/Plugcmds/projectTool/icons/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/projectTool/icons/folder.png
--------------------------------------------------------------------------------
/Plugcmds/projectTool/icons/map_pin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/projectTool/icons/map_pin.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/Vector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/Vector.png
--------------------------------------------------------------------------------
/Plugcmds/projectTool/icons/windowIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/projectTool/icons/windowIcon.png
--------------------------------------------------------------------------------
/Plugcmds/AnimSceneReader/icons/light_on.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/AnimSceneReader/icons/light_on.png
--------------------------------------------------------------------------------
/Plugcmds/AnimSceneReader/icons/map_pin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/AnimSceneReader/icons/map_pin.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/IKControl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/IKControl.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/background_a.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/background_a.png
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/icon/background_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/ControlSelecter/icon/background_b.png
--------------------------------------------------------------------------------
/Plugcmds/CopyBlendShapeWeights/icons/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/CopyBlendShapeWeights/icons/arrow.png
--------------------------------------------------------------------------------
/Plugcmds/AnimSceneReader/icons/blank_folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/AnimSceneReader/icons/blank_folder.png
--------------------------------------------------------------------------------
/Plugcmds/AnimSceneReader/icons/cloud_upload.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/AnimSceneReader/icons/cloud_upload.png
--------------------------------------------------------------------------------
/Plugcmds/CopyBlendShapeWeights/icons/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zclongpop123/RiggingTeamTools/HEAD/Plugcmds/CopyBlendShapeWeights/icons/refresh.png
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | Path = '//bjserver2/WScriptsTool/rig/RiggingTeamTools'
4 | if Path not in sys.path:
5 | sys.path.append(Path)
6 |
7 |
8 | import RootUI
9 | reload(RootUI)
10 | RootUI.PlugTool()
11 |
12 | #
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # toturial folder
2 | tutorail
3 | ToolIndex
4 |
5 |
6 | # Python
7 | *.pyc
8 |
9 |
10 | # wingIDE projFiles
11 | *.wpr
12 | *.wpu
13 |
14 |
15 | # pyCharm projectFiles
16 | .idea
17 |
18 |
19 |
20 | # windows dataBase
21 | *.db
22 |
--------------------------------------------------------------------------------
/Plugcmds/FixShape/Data.json:
--------------------------------------------------------------------------------
1 | [
2 | "L_armShoulder_bnd_0",
3 | "R_armShoulder_bnd_0",
4 | "L_legHip_bnd_0",
5 | "R_legHip_bnd_0",
6 | "L_armElbow_bnd_0",
7 | "R_armElbow_bnd_0",
8 | "L_legKnee_bnd_0",
9 | "R_legKnee_bnd_0"
10 | ]
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/TposeData.py:
--------------------------------------------------------------------------------
1 | import re
2 | dic = {
3 |
4 | 'Global': 0,
5 |
6 | 'follow': 1,
7 |
8 | 'chainStartEnveloppe':1,
9 |
10 | 'StarCurveAttract': 0,
11 |
12 | 'Lenght2':1,
13 |
14 | 'Lenght1':1,
15 |
16 | 'FKIKBlend':1,
17 |
18 | 'minSquash':0.25
19 | }
--------------------------------------------------------------------------------
/Plugcmds/ShapeBuilder/__init__.py:
--------------------------------------------------------------------------------
1 | import os,inspect
2 |
3 | initfile = inspect.getfile(inspect.currentframe())
4 | initdir = os.path.dirname(initfile)
5 | contents = os.listdir(initdir)
6 | modules = []
7 | for m in contents:
8 | if m[-3:] != '.py' or '__init__' in m:
9 | continue
10 | modules.append(m[:-3])
11 | __all__ = modules
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/__init__.py:
--------------------------------------------------------------------------------
1 | import os,inspect
2 |
3 | initfile = inspect.getfile(inspect.currentframe())
4 | initdir = os.path.dirname(initfile)
5 | contents = os.listdir(initdir)
6 | modules = []
7 | for m in contents:
8 | if m[-3:] != '.py' or '__init__' in m:
9 | continue
10 | modules.append(m[:-3])
11 | __all__ = modules
--------------------------------------------------------------------------------
/Plugcmds/ControlSelecter/ControlSelecterUIASSERT.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | icon/background_b.png
4 | icon/hip.png
5 | icon/toe.png
6 | icon/IKControl.png
7 | icon/IKFK.png
8 | icon/SDP.png
9 | icon/Vector.png
10 | icon/background_a.png
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Plugcmds/ConvertControl/ControlParentData.json:
--------------------------------------------------------------------------------
1 | {
2 | "C_jawUpper_jnt_1": [
3 | "A",
4 | "B",
5 | "C"
6 | ],
7 | "C_jawLower_jnt_1": [
8 | "x",
9 | "y",
10 | "z"
11 | ],
12 | "C_mouth_jnt_0": [
13 | "a",
14 | "b",
15 | "c"
16 | ],
17 | "C_head_jnt_0": [
18 | "L_browMain_Tcth_0",
19 | "R_browMain_Tcth_0",
20 | "L_eyeUpperLid_Tcth_0",
21 | "L_eyeLowerLid_Tcth_0",
22 | "R_eyeUpperLid_Tcth_0",
23 | "R_eyeLowerLid_Tcth_0",
24 | "R_eyeCornerOuter_Tcth_0",
25 | "R_eyeCornerInner_Tcth_0",
26 | "L_eyeCornerOuter_Tcth_0",
27 | "L_eyeCornerInner_Tcth_0"
28 | ]
29 | }
--------------------------------------------------------------------------------
/Plugcmds/DynControl/makeScriptNode.mel:
--------------------------------------------------------------------------------
1 | scriptNode -beforeScript "global proc hairAttract_panel_out() \n{ \nglobal string $v_hair_panel; \nstring $selName[] = `ls -sl`; \nif(`objExists(($selName[0]+\".hairAttract_button\"))`) \n{ \n\n\n\nstring $CF[] = `listConnections ($selName[0]+\".hairSystem\")`;\nstring $CFS[]=`listRelatives -s $CF[0]`;\n\nstring $notes = `getAttr ($selName[0]+\".notes\")`; \nif(size($notes)) \n{ \nstring $theobj = ($selName[0]+\".notes\"); \nstring $expObj=`getAttr $theobj`;\nstring $exp=($expObj+\" \"+ $CFS[0]+\".attractionScale\");\neval($exp); \n\n\n} \nelse \n{ \nerror \"please select the correctly facial CTRL ...\"; \n} \nselect -cl; \n} \n \n} \nint $facialPanel = `scriptJob -kws -e \"SelectionChanged\" hairAttract_panel_out`;" -n hairExp;
--------------------------------------------------------------------------------
/Plugcmds/ConvertControl/ControlVisbilityData.json:
--------------------------------------------------------------------------------
1 | {
2 | "VisControl_A": [
3 | "L_browMain_Tctl_0",
4 | "R_browMain_Tctl_0"
5 | ],
6 | "VisControl_B": [
7 | "L_eyeUpperOuterLid_Tctl_0",
8 | "R_eyeUpperOuterLid_Tctl_0",
9 | "L_eyeUpperInnerLid_Tctl_0",
10 | "R_eyeUpperInnerLid_Tctl_0",
11 | "L_eyeLowerOuterLid_Tctl_0",
12 | "R_eyeLowerOuterLid_Tctl_0",
13 | "L_eyeLowerInnerLid_Tctl_0",
14 | "R_eyeLowerInnerLid_Tctl_0",
15 | "L_squint_Tctl_0",
16 | "R_squint_Tctl_0"
17 | ],
18 | "VisControl_C": [
19 | "C_lipUpperMain_Tctl_0",
20 | "C_lipLowerMain_Tctl_0",
21 | "L_mouthCorner_Tctl_0",
22 | "R_mouthCorner_Tctl_0"
23 | ]
24 | }
--------------------------------------------------------------------------------
/FoleyUtils/ioTool.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Fri, 04 Jul 2014 14:25:54
5 | #=============================================
6 | import json
7 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
8 |
9 | def readData(path):
10 | '''
11 | import a file path, read data to return..
12 | '''
13 | f = open(path, 'r')
14 | data = json.load(f)
15 | f.close()
16 | return data
17 |
18 |
19 |
20 | def writeData(path, data):
21 | '''
22 | give a file path and data, write data to file..
23 | Exp:
24 | writeData("D:/Temp.json", {"a":0, "b":1})
25 | '''
26 | f = open(path, 'w')
27 | json.dump(data, f, indent=4)
28 | f.close()
--------------------------------------------------------------------------------
/Plugcmds/StreatchSacleToTranslate.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Fri, 18 Jul 2014 13:58:07
5 | #=============================================
6 | import re
7 | import maya.cmds as mc
8 | import maya.mel as mel
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 | mel.eval('source "C:/Program Files/Autodesk/Maya2013.5/scripts/startup/channelBoxCommand.mel"')
11 |
12 | def breakScale():
13 | Joints = ' '.join(mc.ls(type='joint'))
14 | arm_part_jnts = re.findall('[LR]_\w+Elbow\w*_bnd_\d+', Joints)
15 | leg_part_jnts = re.findall('[LR]_\w+Knee\w*_bnd_\d+', Joints)
16 |
17 | two_part_jnts = []
18 | two_part_jnts.extend(dict.fromkeys(arm_part_jnts).keys())
19 | two_part_jnts.extend(dict.fromkeys(leg_part_jnts).keys())
20 |
21 |
22 | for jnt in two_part_jnts:
23 | mel.eval('CBdeleteConnection "%s.sx";'%jnt)
24 |
25 | print '#- Successed -# Disconnected scale connection for : %s !!'%', '.join(two_part_jnts),
--------------------------------------------------------------------------------
/Plugcmds/old/ClusterWeight.mel:
--------------------------------------------------------------------------------
1 | {
2 | if(`window -ex "ClusterWeightWnd"`){deleteUI -wnd "ClusterWeightWnd";}
3 | if(`windowPref -ex "ClusterWeightWnd"`){windowPref -r "ClusterWeightWnd";}
4 | window -t "Cluster to Joint Weight" -w 300 -h 120 "ClusterWeightWnd";
5 |
6 | columnLayout;
7 | rowColumnLayout -nc 3 -cw 1 220 -cw 2 50 -cw 3 30;
8 | textField "ClusterModelFLD";
9 | button -l " < < <" -c "python(\"LoadOBJ('ClusterModelFLD')\")";
10 | button -l "Sel.." -c "python(\"SelectOBJ('ClusterModelFLD')\")";
11 | textField "SkinModelFLD";
12 | button -l " < < <" -c "python(\"LoadOBJ('SkinModelFLD')\")";
13 | button -l "Sel.." -c "python(\"SelectOBJ('SkinModelFLD')\")";
14 | textField "ClusterNameFLD";
15 | button -l " < < <" -c "python(\"LoadOBJ('ClusterNameFLD')\")";
16 | button -l "Sel.." -c "python(\"SelectOBJ('ClusterNameFLD')\")";
17 | textField "JointNameFLD";
18 | button -l " < < <" -c "python(\"LoadOBJ('JointNameFLD')\")";
19 | button -l "Sel.." -c "python(\"SelectOBJ(''JointNameFLD')\")";
20 | setParent..;
21 | rowColumnLayout -nc 2 -cw 1 150 -cw 2 150;
22 | button -l "<- Joint to cluster ->" -c "python(\"TransWeightToCluster()\")";
23 |
24 | button -l "<- cluster to Joint ->" -c "python(\"TransWeightToJoint()\")";
25 | showWindow "ClusterWeightWnd";
26 | }
--------------------------------------------------------------------------------
/Plugcmds/findCoincidentGeometry/findCoincidentGeometryUI.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Thu, 20 Nov 2014 17:10:31
5 | #========================================
6 | import os.path, time, findCoincidentGeometry
7 | from FoleyUtils import scriptTool, uiTool
8 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
9 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'findCoincidentGeometry.ui'))
10 | class findCoincidentGeometryUI(windowClass, baseClass):
11 | def __init__(self, parent=None):
12 | if uiTool.windowExists(parent, 'findCoincidentGeometryUI'):
13 | return
14 | super(findCoincidentGeometryUI, self).__init__(parent)
15 | self.setupUi(self)
16 | self.show()
17 | #------------------
18 |
19 | def on_pushButton_clicked(self, args=None):
20 | if args == None:return
21 | self.plainTextEdit.setPlainText('')
22 | self.plainTextEdit.appendPlainText('------ %s ------'%time.strftime("%H:%M:%S", time.localtime()))
23 |
24 | geometrys = findCoincidentGeometry.findCoincidentGeometrys()
25 |
26 | self.plainTextEdit.appendPlainText('\n'.join(geometrys))
27 | self.plainTextEdit.appendPlainText('------ %s ------'%time.strftime("%H:%M:%S", time.localtime()))
--------------------------------------------------------------------------------
/FoleyUtils/scriptTool.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 25 Jun 2014 14:43:02
5 | #=============================================
6 | import os, inspect
7 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
8 |
9 | def getModulesPath(moudle):
10 | '''
11 | return dir for imported moudle..
12 | '''
13 | moduleFile = inspect.getfile(moudle)
14 | modulePath = os.path.dirname(moduleFile)
15 | return modulePath
16 |
17 |
18 |
19 |
20 | def getScriptPath():
21 | '''
22 | return dir path for used script..
23 | '''
24 | scriptPath = getModulesPath(inspect.currentframe().f_back)
25 | return scriptPath
26 |
27 |
28 |
29 |
30 |
31 | def arrayRemoveDuplicates(Array):
32 | '''
33 | [1,1,2,2,3,3,4,5,5,6,6,6,6] -> [1,2,3,4,5,6]
34 | '''
35 | if not type(Array) is list:
36 | return Array
37 | return [x for i, x in enumerate(Array) if x not in Array[:i]]
38 |
39 |
40 |
41 |
42 |
43 | def openMultiarray(Array):
44 | '''
45 | [1, [2, [3, 4], 5], 6] -> [1, 2, 3, 4, 5, 6]
46 | (1, (2, (3, 4), 5), 6) -> (1, 2, 3, 4, 5, 6)
47 | '''
48 | L = []
49 | for Item in Array:
50 | if isinstance(Item, (tuple, list)):
51 | for i in openMultiarray(Item):
52 | L.append(i)
53 | else:
54 | L.append(Item)
55 | return L
--------------------------------------------------------------------------------
/Plugcmds/findCoincidentGeometry/findCoincidentGeometry.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | findCoincidentGeometryUI
4 |
5 |
6 |
7 | 0
8 | 0
9 | 240
10 | 360
11 |
12 |
13 |
14 |
15 | 240
16 | 360
17 |
18 |
19 |
20 |
21 | 240
22 | 360
23 |
24 |
25 |
26 | Find Coincident Geometry
27 |
28 |
29 |
30 |
31 | 6
32 |
33 | -
34 |
35 |
36 |
37 | 10
38 |
39 |
40 |
41 | true
42 |
43 |
44 |
45 |
46 |
47 |
48 | -
49 |
50 |
51 |
52 | 0
53 | 25
54 |
55 |
56 |
57 | Go
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Plugcmds/addPalmBindJoint.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as mc
2 |
3 |
4 | def addPalmBindJoint():
5 |
6 | def addJoint(side='L'):
7 | if mc.objExists('%s_armPalm_bnd_0'%side):return
8 |
9 | # make joint and locators
10 | Joint = mc.createNode('joint', name='%s_armPalm_bnd_0'%side)
11 | JointGroup = mc.group(Joint, name='%s_armPalm_bndgrp_0'%side)
12 | FKloc = mc.spaceLocator(p=(0,0,0), name='%s_armPalmFK_loc_0'%side)[0]
13 | IKloc = mc.spaceLocator(p=(0,0,0), name='%s_armPalmIK_loc_0'%side)[0]
14 |
15 | # constraint
16 | constraintNode = mc.parentConstraint(FKloc, IKloc, JointGroup)
17 |
18 | # match position
19 | mc.delete(mc.parentConstraint('%s_armMiddleAIK_jnt_0'%side, FKloc))
20 | mc.delete(mc.parentConstraint('%s_armMiddleAIK_jnt_0'%side, IKloc))
21 |
22 | # parent locator
23 | mc.parent(FKloc, '%s_armWristFk_jnt_0'%side)
24 | mc.parent(IKloc, '%s_armMiddleAIK_jnt_0'%side)
25 |
26 | # make ikfk switch
27 | reverseNode = [x.split('.')[0] for x in mc.connectionInfo('%s_armFkIk_ctl_0.FKIKBlend'%side, dfs=True) if mc.nodeType(x.split('.')[0])=='reverse'][0]
28 | mc.connectAttr('%s.outputX'%reverseNode, '%s.%sW0'%(constraintNode[0], FKloc))
29 | mc.connectAttr('%s_armFkIk_ctl_0.FKIKBlend'%side, '%s.%sW1'%(constraintNode[0], IKloc))
30 |
31 | # add to bind set
32 | mc.sets(Joint, e=True, forceElement='bind_joints_set')
33 |
34 | # connect jointLayer
35 | mc.connectAttr('jointLayer.drawInfo', '%s.drawOverride'%Joint)
36 |
37 | # parent joint
38 | mc.parent(JointGroup, '%s_armBind_org_0'%side)
39 |
40 |
41 | #-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 | for side in 'LR':
43 | addJoint(side)
--------------------------------------------------------------------------------
/Plugcmds/old/ControlColors.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as mc
2 | from functools import partial
3 | import re
4 |
5 |
6 | def showControlWindow():
7 | if mc.window("ControlColors", ex=True):mc.deleteUI("ControlColors", wnd=True)
8 | if mc.windowPref("ControlColors", ex=True):mc.windowPref("ControlColors", r=True)
9 |
10 | mc.window("ControlColors", t="Control Colors", w=320, h=45, menuBar=True)
11 |
12 | ColorRGBIndeX = ((0.000, 0.000, 0.000),(0.000, 0.000, 0.000),(0.251, 0.251, 0.251),(0.500, 0.500, 0.500),(0.608, 0.000, 0.157),(0.000, 0.016, 0.376),(0.000, 0.000, 1.000),(0.000, 0.275, 0.098),(0.149, 0.000, 0.263),(0.784, 0.000, 0.784),(0.541, 0.282, 0.200),(0.247, 0.137, 0.122),(0.600, 0.149, 0.000),(1.000, 0.000, 0.000),(0.000, 1.000, 0.000),(0.000, 0.255, 0.600),(1.000, 1.000, 1.000),(1.000, 1.000, 0.000),(0.392, 0.863, 1.000),(0.263, 1.000, 0.639),(1.000, 0.690, 0.690),(0.894, 0.675, 0.475),(1.000, 1.000, 0.388),(0.000, 0.600, 0.329),(0.631, 0.412, 0.188),(0.624, 0.631, 0.188),(0.408, 0.631, 0.188),(0.188, 0.631, 0.365),(0.188, 0.631, 0.631),(0.188, 0.404, 0.631),(0.435, 0.188, 0.631),(0.631, 0.188, 0.412))
13 | mc.rowColumnLayout(w=320, nc=16, cw=[(i, 20) for i in range(1,17)])
14 | mc.iconTextRadioCollection("UI_ColorCollide")
15 | for i in range(32):
16 | if i == 0:
17 | mc.iconTextRadioButton('UI_ColorRadioBtn%d'%i, h=20, i='fpe_brokenPaths.png', onc=partial(SetDisplayColor))
18 | else:
19 | mc.iconTextRadioButton('UI_ColorRadioBtn%d'%i, h=20, bgc=ColorRGBIndeX[i], onc=partial(SetDisplayColor))
20 | mc.showWindow("ControlColors")
21 |
22 |
23 |
24 |
25 | def SetDisplayColor(Unuse=None):
26 | Value = int(re.search('\d+$', mc.iconTextRadioCollection("UI_ColorCollide", q=True, sl=True)).group())
27 | for OBJ in mc.ls(sl=True):
28 | for shp in mc.listRelatives(OBJ, s=True, path=True) or []:
29 | mc.setAttr(OBJ + '.ove', 1)
30 | mc.setAttr(OBJ + '.ovc', Value)
--------------------------------------------------------------------------------
/Plugcmds/quickSDKTool.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import maya.cmds as mc
3 | from FoleyUtils import scriptTool, uiTool
4 |
5 |
6 | UIwndClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'quickSDKTool.ui'))
7 | class quickSDK(UIwndClass, baseClass):
8 | def __init__(self, parent=None):
9 | if uiTool.windowExists(parent, 'quickSDKwindow'):
10 | return
11 |
12 | super(quickSDK, self).__init__(parent)
13 | self.setupUi(self)
14 | self.show()
15 | #-------------
16 |
17 |
18 | def on_actionLoadAttributes_triggered(self, clicked=None):
19 | if clicked==None:return
20 |
21 |
22 | mainChannelBox = 'mainChannelBox'
23 | ChannelBoxs = mc.lsUI(typ='channelBox')
24 | ChannelBoxs.remove(mainChannelBox)
25 | if len(ChannelBoxs) == 0:return
26 |
27 |
28 |
29 | DriverOBJ = mc.channelBox(mainChannelBox, q=True, mol=True)
30 | DriverAttr = mc.channelBox(mainChannelBox, q=True, sma=True)
31 |
32 |
33 | if not DriverOBJ or not DriverAttr:return
34 | self.driverAttributelineEdit.setText('%s.%s'%(DriverOBJ[0], DriverAttr[0]))
35 |
36 |
37 |
38 | DrivenOBJ = mc.channelBox(ChannelBoxs[0], q=True, mol=True)
39 | DrivenAttr = mc.channelBox(ChannelBoxs[0], q=True, sma=True)
40 | DrivenAttrList = []
41 | for attribute in DrivenAttr:
42 | DrivenAttrList.append('%s.%s'%(DrivenOBJ[0], attribute))
43 | self.drivenAttributelineEdit.clear()
44 | self.drivenAttributelineEdit.addItems(DrivenAttrList)
45 |
46 |
47 |
48 | def on_actionQuickSDK_triggered(self, clicked=None):
49 | if clicked==None:return
50 |
51 | DriverAttribute = str(self.driverAttributelineEdit.text())
52 |
53 |
54 | for i in range(self.drivenAttributelineEdit.count()):
55 | Drivenattr = str(self.drivenAttributelineEdit.item(i).text())
56 | mc.setDrivenKeyframe(Drivenattr, cd=DriverAttribute)
57 |
--------------------------------------------------------------------------------
/Plugcmds/DynControl/hairSystemConnection.txt:
--------------------------------------------------------------------------------
1 | string $name="sz";
2 |
3 |
4 | file -import -type "mayaAscii" -ra true -rpr $name -options "v=0;p=17" -pr -loadReferenceDepth "all" "C:/Users/renjunlu/Desktop/jiesuankaiguan.ma";
5 |
6 | string $hairName=$name+"_hair_ctrl";
7 | string $hairAttracion=$name+"_attractionScale";
8 |
9 |
10 |
11 | string $sel[]=`ls -sl` ;
12 |
13 | connectAttr -f ($sel[0]+".message") ($hairAttracion+".hairSystem");
14 |
15 |
16 | int $hairsize=`size($sel)`;
17 | int $m;
18 |
19 | for ($m=1; $m< $hairsize; $m++)
20 |
21 | {
22 |
23 |
24 |
25 |
26 | connectAttr -f ($sel[0]+".attractionScale[0]") ($sel[$m]+".attractionScale[0]");
27 | connectAttr -f ($sel[0]+".attractionScale[1]") ($sel[$m]+".attractionScale[1]");
28 |
29 |
30 | }
31 |
32 |
33 |
34 | for ($i in $sel)
35 | {
36 |
37 |
38 | connectAttr -f ($hairName+".chainStartFrame") ($i+".startFrame");
39 | connectAttr -f ($hairName+".chainStiffness") ($i+".stiffness");
40 | connectAttr -f ($hairName+".chainDamping") ($i+".damp");
41 | connectAttr -f ($hairName+".chainGravity") ($i+".gravity");
42 | connectAttr -f ($hairName+".chainCollide") ($i+".collide");
43 | connectAttr -f ($hairName+".StarCurveAttract") ($i+".startCurveAttract");
44 |
45 |
46 |
47 | }
48 |
49 |
50 | scriptNode -beforeScript "global proc hairAttract_panel_out() \n{ \nglobal string $v_hair_panel; \nstring $selName[] = `ls -sl`; \nif(`objExists(($selName[0]+\".hairAttract_button\"))`) \n{ \n\n\n\nstring $CF[] = `listConnections ($selName[0]+\".hairSystem\")`;\nstring $CFS[]=`listRelatives -s $CF[0]`;\n\nstring $notes = `getAttr ($selName[0]+\".notes\")`; \nif(size($notes)) \n{ \nstring $theobj = ($selName[0]+\".notes\"); \nstring $expObj=`getAttr $theobj`;\nstring $exp=($expObj+\" \"+ $CFS[0]+\".attractionScale\");\neval($exp); \n\n\n} \nelse \n{ \nerror \"please select the correctly facial CTRL ...\"; \n} \nselect -cl; \n} \n \n} \nint $facialPanel = `scriptJob -kws -e \"SelectionChanged\" hairAttract_panel_out`;" -n hairExp;
51 |
52 |
53 | setAttr "hairExp.scriptType" 1;
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/FoleyUtils/colorTool.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 25 Jun 2014 14:43:02
5 | # http://code.activestate.com/recipes/576919-python-rgb-and-hsv-conversion/
6 | #=============================================
7 | import math, struct
8 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
9 |
10 | def hsv_to_rgb(h, s, v):
11 | '''
12 | import a HSV color, return RGB values..
13 | (0, 0, 100) -> (255, 255, 255)
14 | '''
15 | h, s, v = float(h), float(s), float(v)
16 |
17 | h60 = h / 60.0
18 | h60f = math.floor(h60)
19 | hi = int(h60f) % 6
20 | f = h60 - h60f
21 | p = v * (1 - s)
22 | q = v * (1 - f * s)
23 | t = v * (1 - (1 - f) * s)
24 |
25 | color_dict = {0:(v, t, p), 1:(q, v, p), 2:(p, v, t), 3:(p, q, v), 4:(t, p, v), 5:(v, p, q)}
26 | r, g, b = color_dict.get(hi, (0, 0, 0))
27 | r, g, b = int(r * 255), int(g * 255), int(b * 255)
28 |
29 | return r, g, b
30 |
31 |
32 |
33 |
34 | def rgb_to_hsv(r, g, b):
35 | '''
36 | import a RGB color, return HSV valus..
37 | (255, 255, 255) -> (0, 0, 100)
38 | '''
39 | r, g, b = r/255.0, g/255.0, b/255.0
40 | maxV = max(r, g, b)
41 | minV = min(r, g, b)
42 | df = maxV-minV
43 | if maxV == minV:
44 | h = 0
45 | elif maxV == r:
46 | h = (60 * ((g-b)/df) + 360) % 360
47 | elif maxV == g:
48 | h = (60 * ((b-r)/df) + 120) % 360
49 | elif maxV == b:
50 | h = (60 * ((r-g)/df) + 240) % 360
51 | if maxV == 0:
52 | s = 0
53 | else:
54 | s = df/maxV
55 | v = maxV
56 | return h, s, v
57 |
58 |
59 |
60 |
61 |
62 | def hex_to_rgb(rgbstr):
63 | '''
64 | return RGB value by hex string..
65 | 5a5a5a -> (90, 90, 90)
66 | '''
67 | return struct.unpack('BBB',rgbstr.decode('hex'))
68 |
69 |
70 |
71 |
72 | def rgb_to_hex(r, g, b):
73 | '''
74 | return hex string by RGB color Values..
75 | (90, 90, 90) -> 5a5a5a
76 | '''
77 | return struct.pack('BBB', r, g, b).encode('hex')
--------------------------------------------------------------------------------
/Plugcmds/ControlColors.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as mc
2 |
3 | class ColorButton(object):
4 | def __init__(self, colorID, RGBvalue=(0.0,0.0,0.0)):
5 | self.color = colorID
6 | self.Btn = mc.iconTextButton(w=20, h=20,l='', bgc=RGBvalue, c=self.setColor)
7 |
8 |
9 | def setColor(self):
10 | selectOBJs = mc.ls(sl=True)
11 | for OBJ in selectOBJs:
12 | for shp in mc.listRelatives(OBJ, s=True, path=True) or []:
13 | mc.setAttr(shp + '.ove', 1)
14 | mc.setAttr(shp + '.ovc', self.color)
15 |
16 |
17 | def changeImage(self, Image=None):
18 | if Image == None:return
19 | #if not os.path.isfile(Image):return
20 | mc.iconTextButton(self.Btn, e=True, i=Image)
21 |
22 |
23 |
24 |
25 | class ControlColorWindow(object):
26 | ColorRGBIndeX = ((0.267, 0.267, 0.267),(0.000, 0.000, 0.000),(0.251, 0.251, 0.251),(0.500, 0.500, 0.500),(0.608, 0.000, 0.157),(0.000, 0.016, 0.376),(0.000, 0.000, 1.000),(0.000, 0.275, 0.098),(0.149, 0.000, 0.263),(0.784, 0.000, 0.784),(0.541, 0.282, 0.200),(0.247, 0.137, 0.122),(0.600, 0.149, 0.000),(1.000, 0.000, 0.000),(0.000, 1.000, 0.000),(0.000, 0.255, 0.600),(1.000, 1.000, 1.000),(1.000, 1.000, 0.000),(0.392, 0.863, 1.000),(0.263, 1.000, 0.639),(1.000, 0.690, 0.690),(0.894, 0.675, 0.475),(1.000, 1.000, 0.388),(0.000, 0.600, 0.329),(0.631, 0.412, 0.188),(0.624, 0.631, 0.188),(0.408, 0.631, 0.188),(0.188, 0.631, 0.365),(0.188, 0.631, 0.631),(0.188, 0.404, 0.631),(0.435, 0.188, 0.631),(0.631, 0.188, 0.412))
27 |
28 |
29 | def __init__(self):
30 | if mc.window("ControlColors", ex=True):mc.deleteUI("ControlColors", wnd=True)
31 | if mc.windowPref("ControlColors", ex=True):mc.windowPref("ControlColors", r=True)
32 | #----
33 | mc.window("ControlColors", t="Control Colors", w=320, h=45, menuBar=True)
34 | mc.rowColumnLayout(w=320, nc=16, cw=[(i, 20) for i in range(1,17)])
35 | #----
36 | for i in range(32):
37 | clickButton = ColorButton(i, self.ColorRGBIndeX[i])
38 | if i > 0:continue
39 | clickButton.changeImage('fpe_brokenPaths.png')
40 | #----
41 | mc.showWindow("ControlColors")
42 |
43 |
44 |
45 |
46 | if __name__ == '__main__':ControlColorWindow()
47 |
48 |
--------------------------------------------------------------------------------
/Plugcmds/Tpose.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Fri, 01 Aug 2014 14:22:51
5 | #=============================================
6 |
7 | import re
8 | import maya.cmds as mc
9 | from FoleyUtils import mayaTool
10 |
11 | #=====================================================================================
12 | CONTROL_TYPE = ('_ctl_', '_ctr_')
13 |
14 | TRANS_ATTRIBUTES = ('translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ')
15 | SCACLE_AAARIBUTES = ('scaleX', 'scaleY', 'scaleZ', 'visibility')
16 |
17 | #----------------------------------------------------------------------------------------------------------
18 |
19 | def Set(control):
20 | attributes = mc.listAttr(control, k=True)
21 | if attributes == None:return
22 | for attr in attributes:
23 | #- guess default attributes
24 | defaultValue = 0
25 | if attr in TRANS_ATTRIBUTES:
26 | defaultValue = 0
27 | elif attr in SCACLE_AAARIBUTES:
28 | defaultValue = 1
29 | else:
30 | minV = mc.addAttr('%s.%s'%(control, attr), q=True, min=True) or 0
31 | maxV = mc.addAttr('%s.%s'%(control, attr), q=True, max=True) or 0
32 | defV = mc.addAttr('%s.%s'%(control, attr), q=True, dv=True) or 0
33 |
34 | defaultValue = min(max(minV, defV), maxV)
35 |
36 | #- set attribute
37 | if mc.getAttr('%s.%s'%(control, attr), se=True):
38 | mc.setAttr('%s.%s'%(control, attr), defaultValue)
39 |
40 | #----------------------------------------------------------------------------------------------------------
41 | @mayaTool.undo_decorator
42 | def backtoTpose():
43 | selectControl = mc.ls(sl=True)
44 | if len(selectControl) == 0:
45 | mc.warning('you must select a control (any one) from a character !!!')
46 | return
47 |
48 | #- list all of transforms
49 | transforms = ' '.join(mc.ls(type='transform'))
50 |
51 | #- list all of the controls
52 | controls = re.findall('(\S+(%s)\S+)'%'|'.join(CONTROL_TYPE), transforms)
53 |
54 | #- remove duplicates
55 | controls = [x[0] for x in controls]
56 |
57 | #- do it
58 | for control in controls:
59 | if selectControl[0].rsplit(':', 1)[0] == control.rsplit(':', 1)[0]:
60 | Set(control)
--------------------------------------------------------------------------------
/Plugcmds/RenameJnts.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as mc
2 | from functools import partial
3 | class CompName(object):
4 | def __init__(self):
5 | self.LRDt = {1:'L_', -1:'R_', 0:'C_'}
6 | mc.button(h=26, l=self.BtnLab, c=partial(self.RenameJnts), p='BtnLayout')
7 |
8 |
9 | def RenameJnts(self, unuse):
10 | SelJnt = mc.ls(sl=True)
11 | for Jnt, nmLab in zip(SelJnt, self.Nms):
12 | Xvalue = mc.xform(Jnt, q=True, ws=True, t=True)[0]
13 | mc.rename(Jnt, nmLab.replace('L_', self.LRDt[cmp(Xvalue, 0)]))
14 |
15 |
16 | class Spine(CompName):
17 | BtnLab = 'Spine (8)'
18 | Nms = ('C_root_bnd_0', 'C_backA_bnd_0', 'C_backB_bnd_0', 'C_chest_bnd_0', 'C_neck_bnd_0', 'C_neckend_bnd_0', 'C_head_bnd_0', 'C_skull_bnd_0')
19 |
20 |
21 | class Arm(CompName):
22 | BtnLab='Arm (4)'
23 | Nms = ('L_armClavicle_bnd_0', 'L_armShoulder_bnd_0', 'L_armElbow_bnd_0', 'L_armWrist_bnd_0')
24 |
25 |
26 | class ThumbFin(CompName):
27 | BtnLab='Thumb (4)'
28 | Nms = ('L_armThumbA_bnd_0', 'L_armThumbB_bnd_0', 'L_armThumbC_bnd_0', 'L_armThumbD_bnd_0')
29 |
30 |
31 | class IndexFin(CompName):
32 | BtnLab='Index (4)'
33 | Nms = ('L_armIndexA_bnd_0', 'L_armIndexB_bnd_0', 'L_armIndexC_bnd_0', 'L_armIndexD_bnd_0')
34 |
35 |
36 | class MiddleFin(CompName):
37 | BtnLab = 'Middle (4)'
38 | Nms = ('L_armMiddleA_bnd_0', 'L_armMiddleB_bnd_0', 'L_armMiddleC_bnd_0', 'L_armMiddleD_bnd_0')
39 |
40 |
41 | class PinkeyFin(CompName):
42 | BtnLab = 'Pinkey (5)'
43 | Nms = ('L_armCup_bnd_0', 'L_armPinkyA_bnd_0', 'L_armPinkyB_bnd_0', 'L_armPinkyC_bnd_0', 'L_armPinkyD_bnd_0')
44 |
45 |
46 | class Leg(CompName):
47 | BtnLab = 'Leg (5)'
48 | Nms = ('L_legHip_bnd_0', 'L_legKnee_bnd_0', 'L_legAnkle_bnd_0', 'L_legToes_bnd_0', 'L_legToe_bnd_0')
49 |
50 |
51 | def setupRename():
52 | if mc.window('CompNameWnd', ex=True): mc.deleteUI('CompNameWnd', wnd=True)
53 | if mc.windowPref('CompNameWnd', ex=True): mc.windowPref('CompNameWnd', r=True)
54 |
55 | mc.window('CompNameWnd', t=' ', wh=(360,56))
56 | mc.columnLayout()
57 | mc.rowColumnLayout('BtnLayout', nc=4, cw=((1, 90), (3, 89), (2, 89), (4, 90)))
58 | mc.showWindow()
59 | Spine()
60 | Arm()
61 | Leg()
62 | mc.text(l='', p='BtnLayout')
63 | ThumbFin()
64 | IndexFin()
65 | MiddleFin()
66 | PinkeyFin()
67 |
68 |
69 | if __name__ == '__main__': setupRename()
70 |
--------------------------------------------------------------------------------
/Plugcmds/addGroups/addGroups.py:
--------------------------------------------------------------------------------
1 | #=================================
2 | # author: changlong.zang
3 | # date: 2014-06-23
4 | #=================================
5 | import os.path
6 | import maya.cmds as mc
7 | from PyQt4 import QtGui
8 | from FoleyUtils import scriptTool, uiTool
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 |
11 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'addGroups.ui'))
12 | class AddGroup(windowClass, baseClass):
13 | '''
14 | user control pannel...
15 | '''
16 | def __init__(self, parent=None):
17 | if uiTool.windowExists(parent, 'addGroupWindow'):
18 | return
19 |
20 | super(AddGroup, self).__init__(parent)
21 | self.setupUi(self)
22 | self.show()
23 |
24 | def on_btn_append_clicked(self, args=None):
25 | if args == None:return
26 | lineEdit = QtGui.QLineEdit(self.scrollArea)
27 | font = QtGui.QFont()
28 | font.setPointSize(10)
29 | lineEdit.setFont(font)
30 | lineEdit.setMinimumHeight(25)
31 | self.verticalLayout_4.insertWidget(self.verticalLayout_4.count()-1, lineEdit)
32 | lineEdit.setFocus()
33 |
34 |
35 | def on_btn_remove_clicked(self, args=None):
36 | if args == None:return
37 | LineEdits = self.scrollArea.findChildren(QtGui.QLineEdit)
38 | if len(LineEdits) == 1:return
39 | LineEdits.pop().deleteLater()
40 | LineEdits[-1].setFocus()
41 |
42 |
43 |
44 | def on_btn_add_clicked(self, args=None):
45 | if args == None:return
46 |
47 | search = str(self.let_Search.text())
48 | selObj = mc.ls(sl=True)
49 | nameLabels = [str(x.text()) for x in self.scrollArea.findChildren(QtGui.QLineEdit)]
50 | nameLabels.reverse()
51 |
52 | for obj in selObj:
53 | for replace in nameLabels:
54 | if obj.strip() == '':continue
55 | addGroup(obj, search, replace)
56 |
57 |
58 |
59 |
60 | def addGroup(obj, search, replace):
61 | transform = mc.createNode('transform', n=obj.replace(search, replace))
62 | mc.delete(mc.parentConstraint(obj, transform))
63 |
64 | objParent = mc.listRelatives(obj, p=True, path=True)
65 | if objParent:
66 | mc.parent(transform, objParent)
67 | mc.parent(obj, transform)
--------------------------------------------------------------------------------
/Plugcmds/ControlColor.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 03 Dec 2014 18:25:09
5 | #========================================
6 | import FoleyUtils.uiTool, PyQt4.QtGui, functools, maya.cmds
7 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
8 | BUTTON_COLOR_RGB_VALUE = (( 68, 68, 68),( 0, 0, 0),( 64, 64, 64),(128,128,128),(155, 0, 40),( 0, 4, 96),( 0, 0,255),( 0, 70, 25),
9 | ( 38, 0, 67),(200, 0,200),(138, 72, 51),( 63, 35, 31),(153, 38, 0),(255, 0, 0),( 0,255, 0),( 0, 65,153),
10 | (255,255,255),(255,255, 0),(100,220,255),( 67,255,163),(255,176,176),(228,172,121),(255,255, 99),( 0,153, 84),
11 | (161,105, 48),(159,161, 48),(104,161, 48),( 48,161, 93),( 48,161,161),( 48,103,161),(111, 48,161),(161, 48,105))
12 |
13 | class ColorWindow(PyQt4.QtGui.QMainWindow):
14 | windowName = 'DragonDreamsControlColorToolWindow'
15 |
16 | def __init__(self, parent=None):
17 | if FoleyUtils.uiTool.windowExists(parent, self.windowName):
18 | return
19 |
20 | #- setup window
21 | super(ColorWindow, self).__init__(parent)
22 | self.setObjectName(self.windowName)
23 | self.setWindowTitle('Control Color Tool')
24 | self.setMaximumSize (482, 62)
25 | self.setMinimumSize (482, 62)
26 |
27 | #- add buttons
28 | for i in range(32):
29 | btn = PyQt4.QtGui.QPushButton(self)
30 | px = i % 16 * 30 + 1
31 | py = i // 16 * 30 + 1
32 | sx = 30
33 | sy = 30
34 | btn.setGeometry(px, py, sx, sy)
35 |
36 | btn.clicked.connect(functools.partial(self.setColor, i))
37 | btn.setStyleSheet('background-color: rgb(%d, %d, %d);'%BUTTON_COLOR_RGB_VALUE[i])
38 |
39 | self.show()
40 |
41 |
42 | def setColor(self, colorIndex):
43 | selectObjects = maya.cmds.ls(sl=True)
44 | if len(selectObjects) == 0:
45 | return
46 |
47 | for shp in maya.cmds.listRelatives(selectObjects, s=True, path=True) or []:
48 | if colorIndex == 0:
49 | maya.cmds.setAttr(shp + '.ove', 0)
50 | else:
51 | maya.cmds.setAttr(shp + '.ove', 1)
52 | maya.cmds.setAttr(shp + '.ovc', colorIndex)
--------------------------------------------------------------------------------
/Plugcmds/latticeWeightsTool.py:
--------------------------------------------------------------------------------
1 | import json
2 | from functools import partial
3 | import maya.cmds as mc
4 | import maya.mel as mel
5 | class latticeWeightTool(object):
6 | def __init__(self):
7 |
8 | if mc.window('latticeWeiWnd', ex=True): mc.deleteUI('latticeWeiWnd', wnd=True)
9 | if mc.windowPref('latticeWeiWnd', ex=True): mc.windowPref('latticeWeiWnd', r=True)
10 |
11 | mc.window('latticeWeiWnd', wh=(300, 30), t='Lattice Weights')
12 | mc.columnLayout()
13 | mc.rowColumnLayout(nc=2, cw=((1,149), (2,149)))
14 | mc.button(h=26, l='Save', c=partial(self.SaveWeight))
15 | mc.button(l='Load', c=partial(self.LaodWeight))
16 | mc.showWindow('latticeWeiWnd')
17 |
18 |
19 |
20 | def SaveWeight(self, Unuse):
21 | FileFullpath = mc.fileDialog2(ff=("JSON Files (*.json)"))
22 | if FileFullpath == None:return
23 | latice = mc.ls(sl=True)
24 | latticePT = mc.lattice(latice[0], q=True, dv=True)
25 |
26 | SkinUseDt = {}
27 | SkinUseDt['skinNode'] = mel.eval('findRelatedSkinCluster ' + latice[0])
28 | SkinUseDt['skinJoints'] = mc.skinCluster(latice[0], q=True, inf=True)
29 |
30 |
31 | for x in range(latticePT[0]):
32 | for y in range(latticePT[1]):
33 | for z in range(latticePT[2]):
34 | Pts = '%s.pt[%d][%d][%d]' %(latice[0], x, y, z)
35 | weightList = mc.skinPercent(SkinUseDt['skinNode'], Pts, q=True, v=True)
36 | SkinUseDt.setdefault('weightList', {})['pt[%d][%d][%d]' %(x, y, z)] = weightList
37 |
38 |
39 | f = open(FileFullpath[0], mode='w')
40 | json.dump(SkinUseDt, f, indent=2)
41 | f.close()
42 | print '# Result: weight was saved to -> %s ' %FileFullpath[0],
43 |
44 |
45 | def LaodWeight(self, Unuse):
46 | FileFullpath = mc.fileDialog2(fm=1, ff=("JSON Files (*.json)"))
47 | if FileFullpath == None:return
48 |
49 | f = open(FileFullpath[0], mode='r')
50 | fileDt = json.load(f)
51 | f.close()
52 |
53 | latice = mc.ls(sl=True)
54 | skinNode = mel.eval('findRelatedSkinCluster ' + latice[0])
55 | for pt, Weilist in fileDt['weightList'].iteritems():
56 | mc.skinPercent(skinNode, '%s.%s'%(latice[0], pt), tv=zip(fileDt['skinJoints'], Weilist))
57 |
58 | print '# Result: weight Read Final! ',
59 | #------------------------------------------------------------------------------------------------
60 | if __name__ == '__main__':latticeWeightTool()
61 |
--------------------------------------------------------------------------------
/Plugcmds/saveDrivenKeys.py:
--------------------------------------------------------------------------------
1 | from PyQt4 import QtCore, QtGui
2 | import maya.cmds as mc
3 | import rigBuilder.face.faceIO
4 | from FoleyUtils import uiTool
5 |
6 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
7 |
8 | class SaveDrivenKeyWindow(QtGui.QMainWindow):
9 | def __init__(self, parent=None):
10 | if uiTool.windowExists(parent, 'saveDrivenkeysWindow'):
11 | return
12 | super(SaveDrivenKeyWindow, self).__init__(parent)
13 | self.setupUi()
14 | self.setObjectName('saveDrivenkeysWindow')
15 | #------------------------------------------------
16 | self.loadButton.clicked.connect(self.loadKeys)
17 | self.saveButton.clicked.connect(self.saveKeys)
18 | #------------------------------------------------
19 |
20 |
21 | def setupUi(self):
22 | self.setObjectName('SaveDrivenKeyWindow')
23 | self.setWindowTitle('Save DrivenKey')
24 | self.resize(240, 43)
25 | self.setMinimumSize(QtCore.QSize(240, 43))
26 | self.setMaximumSize(QtCore.QSize(240, 43))
27 |
28 | self.centralwidget = QtGui.QWidget(self)
29 | self.centralwidget.setObjectName('centralwidget')
30 |
31 | self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
32 | self.horizontalLayout.setSpacing(2)
33 | self.horizontalLayout.setObjectName('horizontalLayout')
34 |
35 | self.loadButton = QtGui.QPushButton('Load', self.centralwidget)
36 | self.loadButton.setMinimumSize(QtCore.QSize(0, 26))
37 | self.loadButton.setMaximumSize(QtCore.QSize(16777215, 26))
38 | self.loadButton.setObjectName('loadButton')
39 | self.horizontalLayout.addWidget(self.loadButton)
40 |
41 | self.saveButton = QtGui.QPushButton('Save', self.centralwidget)
42 | self.saveButton.setMinimumSize(QtCore.QSize(0, 26))
43 | self.saveButton.setMaximumSize(QtCore.QSize(16777215, 26))
44 | self.saveButton.setObjectName('saveButton')
45 | self.horizontalLayout.addWidget(self.saveButton)
46 | self.setCentralWidget(self.centralwidget)
47 | self.show()
48 |
49 |
50 | def loadKeys(self, args=None):
51 | filePath = mc.fileDialog2(fm=1, ff='JSON Files(*.json)')
52 | if not filePath:return
53 | rigBuilder.face.faceIO.importSceneDrivenKeyData(filePath[0], verbose=True)
54 |
55 | def saveKeys(self, args=None):
56 | filePath = mc.fileDialog2(fm=0, ff='JSON Files(*.json)')
57 | if not filePath:return
58 | rigBuilder.face.faceIO.exportSceneDrivenKeyData(filePath[0], verbose=True)
--------------------------------------------------------------------------------
/Plugcmds/mirrorFaceControlDrivenkeys.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Mon, 09 Mar 2015 14:38:00
5 | #========================================
6 | import re
7 | import maya.cmds as mc
8 | from FoleyUtils import uiTool
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 | def getDrivenKeys(obj):
11 | keys = mc.listConnections(obj, t='animCurve') or []
12 | for unc in mc.listConnections(obj, t='unitConversion') or []:
13 | keys.extend(mc.listConnections(unc, t='animCurve') or list())
14 |
15 | for k in keys:
16 | driver = mc.connectionInfo('%s.input'%k, sfd=True)
17 | driven = mc.connectionInfo('%s.output'%k, dfs=True)
18 | if not driver or not driven:
19 | continue
20 | if mc.nodeType(driver) == 'unitConversion':
21 | driver = mc.connectionInfo('%s.input'%driver.split('.')[0], sfd=True)
22 |
23 | yield driver, driven[0]
24 |
25 |
26 |
27 | def mirrorDrivenkeys(src, dst):
28 | for driver, driven in getDrivenKeys(src):
29 | newDriver = driver.replace(src, dst)
30 | newDriven = driven.replace('L_', 'R_')
31 | if not mc.objExists(newDriven) or newDriven == driven:
32 | newDriven = driven.replace('left', 'right')
33 | if not mc.objExists(newDriven) or newDriven == driven:
34 | newDriven = driven.replace('L', 'R')
35 |
36 | if not mc.objExists(newDriver) or not mc.objExists(newDriven):
37 | continue
38 | if newDriven == driven:
39 | continue
40 |
41 | driverValues = mc.keyframe(driven, q=True, fc=True)
42 | drivenValues = mc.keyframe(driven, q=True, vc=True)
43 | for drv, dnv in zip(driverValues, drivenValues):
44 | if re.search('(translateX|eyeRotInner_ctl_0.rotateZ|mouthCorner_ctl_0\.translateY|mouth_ctl_0\.translateY)$', newDriver):
45 | dnv = dnv * -1
46 | if re.search('(mainCheek_ctl_0\.translateX)$', newDriver):
47 | dnv = dnv * -1
48 | mc.setDrivenKeyframe(newDriven, cd=newDriver, dv=drv, v=dnv)
49 |
50 | print 'Copy Driven keys: %s : %s -> %s : %s'%(driver, driven, newDriver, newDriven)
51 |
52 |
53 |
54 | def mirrorDrivenkeyByControls():
55 | if not uiTool.warning(message='Mirror face control\'s drivenKeys? ?'):
56 | return
57 | controls = mc.ls('L_*_ctl_*', type='transform')
58 | for src in controls:
59 | dst = src.replace('L_', 'R_')
60 | if not mc.objExists(dst):
61 | continue
62 | mirrorDrivenkeys(src, dst)
--------------------------------------------------------------------------------
/Plugcmds/projectTool/ProjectTool_UI.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | ProjectWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 338
10 | 428
11 |
12 |
13 |
14 | Project Tool
15 |
16 |
17 |
18 |
19 | 2
20 |
21 |
22 | 2
23 |
24 | -
25 |
26 |
-
27 |
28 |
29 | Qt::Horizontal
30 |
31 |
32 |
33 | 40
34 | 20
35 |
36 |
37 |
38 |
39 | -
40 |
41 |
42 |
43 | 13
44 | 75
45 | true
46 |
47 |
48 |
49 | PointingHandCursor
50 |
51 |
52 | QPushButton{
53 | background-color: rgba(255, 255, 255, 0);
54 | selection-background-color: rgba(255, 255, 255, 0);
55 | }
56 | QPushButton::hover{
57 |
58 | color: rgb(170, 255, 127);
59 | }
60 |
61 |
62 |
63 | { $Project }
64 |
65 |
66 |
67 | 20
68 | 20
69 |
70 |
71 |
72 |
73 |
74 |
75 | -
76 |
77 |
78 | QTableView{
79 | background-color: rgb(98,98, 98);
80 | alternate-background-color: rgb(108, 112, 108);
81 | }
82 |
83 |
84 | true
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/Plugcmds/createControlSet.py:
--------------------------------------------------------------------------------
1 | #=================================
2 | # author: changlong.zang
3 | # date: 2014-06-10
4 | #=================================
5 | import os.path
6 | from FoleyUtils import scriptTool, uiTool
7 | import maya.cmds as mc
8 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
9 |
10 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'createControlSet.ui'))
11 | class CreateControlSetUI(windowClass, baseClass):
12 | def __init__(self, parent=None):
13 | if uiTool.windowExists(parent, 'makeControlSetUI'):
14 | return
15 | super(CreateControlSetUI, self).__init__(parent)
16 | self.setupUi(self)
17 | self.show()
18 |
19 | #=============================================================================================
20 | def __createSet(self, name):
21 | if not mc.objExists(name):
22 | mc.sets(n=name, em=True)
23 | if name != 'Allctrls': return
24 |
25 | if mc.objExists('body_Ctrls'):
26 | mc.sets('body_Ctrls', add=name)
27 |
28 | if mc.objExists('facial_Ctrls'):
29 | mc.sets('facial_Ctrls', add=name)
30 |
31 |
32 | def __addMembers(self, name):
33 | selObj = mc.ls(sl=True)
34 | if selObj == []:return
35 | mc.sets(selObj, add=name)
36 |
37 |
38 | def on_btn_AllAddMebbers_clicked(self, args=None):
39 | if args == None:return
40 | self.__createSet('Allctrls')
41 | self.__addMembers('Allctrls')
42 |
43 |
44 | def on_btn_BodyAddMebbers_clicked(self, args=None):
45 | if args == None:return
46 | self.__createSet('body_Ctrls')
47 | self.__addMembers('body_Ctrls')
48 |
49 |
50 | def on_btn_FaceAddMebbers_clicked(self, args=None):
51 | if args == None:return
52 | self.__createSet('facial_Ctrls')
53 | self.__addMembers('facial_Ctrls')
54 |
55 | #=============================================================================================
56 |
57 | def __removeMembers(self, name):
58 | if not mc.objExists(name):return
59 | selObj = mc.ls(sl=True)
60 | if selObj == []:return
61 | mc.sets(selObj, remove=name)
62 |
63 |
64 | def on_btn_AllRemoveMebbers_clicked(self, args=None):
65 | if args == None:return
66 | self.__removeMembers('Allctrls')
67 |
68 |
69 | def on_btn_BodyRemoveMebbers_clicked(self, args=None):
70 | if args == None:return
71 | self.__removeMembers('body_Ctrls')
72 |
73 |
74 | def on_btn_FaceRemoveMebbers_clicked(self, args=None):
75 | if args == None:return
76 | self.__removeMembers('facial_Ctrls')
77 |
78 | #=============================================================================================
--------------------------------------------------------------------------------
/Plugcmds/ReplaceUV/RemoveUVWasteNode.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as cmds
2 |
3 | def RemoveUVWasteNode():
4 | cmds.select(hierarchy=True)
5 | sels = cmds.ls(selection=True, long=True)
6 | for sel in sels:
7 | obj = sel
8 | if (cmds.nodeType(sel) == 'mesh'):
9 | trans = cmds.listRelatives(sel, p=True, f=True)
10 | obj = trans[0]
11 | if ((cmds.nodeType(obj) == 'transform') and delUVTransferAttributesNode(obj)):
12 | pass
13 |
14 |
15 |
16 |
17 | def delUVTransferAttributesNode(obj):
18 | SH = cmds.listRelatives(obj, s=True, f=True, ni=True, type='mesh')
19 | allSH = cmds.listRelatives(obj, s=True, f=True, type='mesh')
20 | orgSH = []
21 | deformers = []
22 | inputType = ('skinCluster', 'blendShape', 'ffd', 'wrap', 'cluster', 'nonLinear', 'sculpt', 'jiggle', 'wire', 'groupParts', 'groupId')
23 | deformerType = ('skinCluster', 'blendShape', 'ffd', 'wrap', 'cluster', 'nonLinear', 'sculpt', 'jiggle', 'wire')
24 | hist = cmds.listHistory(obj)
25 | for histIt in hist:
26 | ListNode = cmds.nodeType(histIt)
27 | if (deformerType.count(ListNode) and deformers.append(histIt)):
28 | pass
29 |
30 | for itSH in allSH:
31 | if (cmds.getAttr((itSH + '.intermediateObject')) and (cmds.listConnections(itSH, d=False) == None)):
32 | orgSH.append(itSH)
33 |
34 | if (len(SH) == 1):
35 | imputNode = cmds.listConnections((SH[0] + '.inMesh'), d=False, sh=True)
36 | if (len(imputNode) and (inputType.count(cmds.nodeType(imputNode)) != True)):
37 | if len(orgSH):
38 | mesh = cmds.createNode('mesh')
39 | for orgIt in orgSH:
40 | cmds.connectAttr((SH[0] + '.outMesh'), (mesh + '.inMesh'), f=True)
41 | cmds.refresh()
42 | cmds.disconnectAttr((SH[0] + '.outMesh'), (mesh + '.inMesh'))
43 | cmds.polyTransfer(orgIt, v=False, vc=False, uv=True, ao=mesh)
44 | transfer = cmds.listConnections(orgIt, d=False)
45 | NewOrg = cmds.listConnections((transfer[0] + '.inputPolymesh'), d=False, sh=True)
46 | cmds.delete(NewOrg)
47 |
48 | if cmds.delete(cmds.listRelatives(mesh, p=True, f=True)):
49 | pass
50 |
51 | n = True
52 | while n:
53 | inputNode = cmds.listConnections((SH[0] + '.inMesh'), d=False, sh=True)
54 | if (len(inputNode) is None):
55 | n = False
56 | break
57 | breakWhile = []
58 | selINode = cmds.nodeType(inputNode)
59 | breakWhile.append(str(selINode))
60 | if (inputType.count(breakWhile) == True):
61 | n = False
62 | break
63 | cmds.delete(inputNode)
64 | n = False
--------------------------------------------------------------------------------
/Plugcmds/ChangeOBJpivot.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | import maya.cmds as mc
3 | from FoleyUtils import scriptTool, uiTool
4 |
5 |
6 | UIwndClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'ChangeOBJpivot.ui'))
7 | class ChangeOBJpivot(UIwndClass, baseClass):
8 | def __init__(self, parent=None):
9 | if uiTool.windowExists(parent, 'changeObjectPivotWindow'):
10 | return
11 |
12 | super(ChangeOBJpivot, self).__init__(parent)
13 | self.setupUi(self)
14 | self.show()
15 | #-------------
16 |
17 |
18 | def on_actionLoadMoveOBJ_triggered(self, args=None):
19 | if args==None:return
20 | SelectOBJ = mc.ls(sl=True)
21 | if len(SelectOBJ) == 0:return
22 | if SelectOBJ[0] == str(self.KeepedOBJLineEdit.text()):return
23 |
24 | self.MovedOBJLineEdit.setText(SelectOBJ[0])
25 |
26 |
27 |
28 |
29 | def on_actionLoadKeepOBJ_triggered(self, args=None):
30 | if args==None:return
31 | SelectOBJ = mc.ls(sl=True)
32 | if len(SelectOBJ) == 0:return
33 | if SelectOBJ[0] == str(self.MovedOBJLineEdit.text()):return
34 | self.KeepedOBJLineEdit.setText(SelectOBJ[0])
35 |
36 |
37 |
38 |
39 |
40 | def on_actionStartMove_triggered(self, args=None):
41 | if args==None:return
42 | toMoveOBJ = str(self.MovedOBJLineEdit.text())
43 | toKeepOBJ = str(self.KeepedOBJLineEdit.text())
44 |
45 | if not mc.objExists(toMoveOBJ) or not mc.objExists(toKeepOBJ):return
46 | if toMoveOBJ == toKeepOBJ:return
47 |
48 |
49 | self.ConstraintDT = {}
50 | self.ConstraintLocators = []
51 |
52 |
53 | for Jnt in (toKeepOBJ, toMoveOBJ):
54 | OldConstraintNode = [x for x in mc.listRelatives(Jnt, c=True, path=True) or [] if mc.nodeType(x).endswith('Constraint')]
55 | for OCSN in OldConstraintNode:
56 | ConstraintType = mc.nodeType(OCSN)
57 | ConstraintOBJ = eval('mc.%s("%s", q=True, tl=True)'%(ConstraintType, OCSN))
58 |
59 | self.ConstraintDT.setdefault(Jnt, {})['type'] = ConstraintType
60 | self.ConstraintDT.setdefault(Jnt, {})['ConsOBJ'] = ConstraintOBJ
61 | mc.delete(OCSN)
62 |
63 |
64 | Loc = mc.spaceLocator(p=(0,0,0))
65 | mc.delete(mc.parentConstraint(Jnt, Loc))
66 | ConstraintNode = mc.parentConstraint(Loc[0], Jnt)
67 |
68 | self.ConstraintLocators.append(Loc[0])
69 | self.ConstraintLocators.append(ConstraintNode[0])
70 |
71 |
72 |
73 |
74 | def on_actionEndMove_triggered(self, args=None):
75 | if args==None:return
76 | if not hasattr(self, 'ConstraintLocators'):return
77 | if self.ConstraintLocators == []: return
78 |
79 | mc.delete(self.ConstraintLocators)
80 | for Jnt in self.ConstraintDT.iterkeys():
81 | eval('mc.%s(%s,"%s", mo=True)'%(self.ConstraintDT[Jnt]['type'], self.ConstraintDT[Jnt]['ConsOBJ'], Jnt))
82 |
--------------------------------------------------------------------------------
/FoleyUtils/mathTool.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 25 Jun 2014 14:43:02
5 | #=============================================
6 | import math
7 | import maya.cmds as mc
8 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
9 |
10 |
11 | def getIntLength(intValue):
12 | '''
13 | Get the how many digits in a int..
14 | Exp:
15 | 8 -> 1
16 | 86 -> 2
17 | 835 -> 3
18 | ...
19 | 96158 -> 5
20 | '''
21 | i = 1
22 | d = 1
23 | while True:
24 | if abs(intValue) // d < 10:
25 | return i
26 | i += 1
27 | d *= 10
28 |
29 |
30 |
31 |
32 | def clamp(minV, maxV, value):
33 | '''
34 | 0, 10, 5 -> 5
35 | 0, 10, -1 -> 0
36 | 0, 10, 11 -> 10
37 | '''
38 | return min(max(minV, value), maxV)
39 |
40 |
41 |
42 |
43 | def setRange(oldMin, oldMax, newMin, newMax, value):
44 | '''
45 | 0 - 10 ---> 0 - 100
46 | | |
47 | 5 -> 50
48 | '''
49 | result = ((float(value) - oldMin) / (oldMax - oldMin) * (newMax - newMin)) + newMin
50 | return result
51 |
52 |
53 |
54 |
55 | def advanceSin(startValue, endValue, inputV):
56 | '''
57 | convert a range value to sin 0 - sin 180
58 | '''
59 | angleValue = setRange(startValue, endValue, 0, 180, inputV)
60 | sinValue = math.sin(angleValue * math.pi / 180.0)
61 | return sinValue
62 |
63 |
64 |
65 |
66 | def converse(startValue, endValue, inputValue):
67 | '''
68 | 0.0, 0.1, 0.2 ... 0.7, 0.8, 0.9, 1.0, 0.9, 0.8, 0.7, ... 0.2, 0.1, 0.0
69 | '''
70 | x = setRange(startValue, endValue, -1, 1, inputValue)
71 | result = 1 - abs(x)
72 | return result
73 |
74 |
75 |
76 |
77 |
78 | def getPoleVectorPosition(Root, Mid, Tip):
79 | '''
80 | # * (Root)
81 | # *
82 | # *
83 | # *
84 | # *
85 | # *
86 | # * (Mid) -----------> * (poleVector[X, Y, Z])
87 | # *
88 | # *
89 | # * (Tip)
90 | '''
91 | #-----------------------------------------------------------
92 | A = mc.xform(Root, q=True, ws=True, t=True)
93 | B = mc.xform(Mid, q=True, ws=True, t=True)
94 | C = mc.xform(Tip, q=True, ws=True, t=True)
95 |
96 | AB = math.sqrt((A[0] - B[0]) ** 2 + (A[1] - B[1]) ** 2 + (A[2] - B[2]) ** 2)
97 | BC = math.sqrt((B[0] - C[0]) ** 2 + (B[1] - C[1]) ** 2 + (B[2] - C[2]) ** 2)
98 | AC = math.sqrt((A[0] - C[0]) ** 2 + (A[1] - C[1]) ** 2 + (A[2] - C[2]) ** 2)
99 |
100 | AD = (AB ** 2 + AC ** 2 - BC**2 ) / (AC * 2)
101 | ADpr = AD / AC
102 |
103 | D = ((C[0] - A[0]) * ADpr + A[0], (C[1] - A[1]) * ADpr + A[1], (C[2] - A[2]) * ADpr + A[2])
104 | BD = math.sqrt((B[0] - D[0]) ** 2 + (B[1] - D[1]) ** 2 + (B[2] - D[2]) ** 2)
105 | ScaleV = (AB + BC) / BD
106 | VectorPosition = ((B[0] - D[0]) * ScaleV + D[0], (B[1] - D[1]) * ScaleV + D[1], (B[2] - D[2]) * ScaleV + D[2])
107 |
108 | return VectorPosition
--------------------------------------------------------------------------------
/Plugcmds/old/ClusterWeight.py:
--------------------------------------------------------------------------------
1 | import re
2 | import maya.cmds as mc
3 | import maya.mel as mel
4 |
5 |
6 | def LoadOBJ(FLDname):
7 | if len(mc.ls(sl=True)) == 0:
8 | mc.textField(FLDname, e=True, tx='')
9 | else:
10 | mc.textField(FLDname, e=True, tx=mc.ls(sl=True)[0])
11 |
12 |
13 | def SelectOBJ(FLDname):
14 | OBJname = mc.textField(FLDname, q=True, tx=True)
15 | if OBJname == '':
16 | pass
17 | else:
18 | mc.select(OBJname)
19 |
20 |
21 |
22 | def TransWeightToJoint():
23 |
24 | ModelName = mc.textField('ClusterModelFLD', q=True, tx=True)
25 | SkinModel = mc.textField('SkinModelFLD', q=True, tx=True)
26 | ClusterName = mc.textField('ClusterNameFLD', q=True, tx=True)
27 | JointName = mc.textField('JointNameFLD', q=True, tx=True)
28 | #- get the cluster Node Name..
29 | if mc.nodeType(ClusterName) == 'transform':
30 | ClusterName = mc.listConnections(ClusterName, t='cluster')[0]
31 | else:
32 | pass
33 |
34 | #- get the Model Id and connect groupparts
35 | ModeID = mc.listRelatives(mc.cluster(ClusterName, q=True, g=True), p=True).index(ModelName)
36 | GroupParts = mc.connectionInfo(ClusterName + '.input[%d].inputGeometry'%ModeID, sfd=True).split('.')[0]
37 |
38 |
39 | #- get Inflution Vts
40 | Points = ['%s.%s'%(ModelName,Vtx) for Vtx in mc.getAttr(GroupParts + '.inputComponents')]
41 |
42 |
43 | #- get Cluster Value
44 | WeightDT = {}
45 | for VVtx in mc.ls(Points, fl=True):
46 | VtxID = re.search('(?<=\[)\d+(?=\])', VVtx).group()
47 | WeightValue = mc.percent(ClusterName, VVtx, q=True, v=True)
48 | WeightDT[VtxID] = WeightValue[0]
49 |
50 | #- get SkinNode Name
51 | SkinClusterNode = mel.eval('findRelatedSkinCluster ' + SkinModel)
52 |
53 |
54 | #- Remove Joint weights
55 | ModelVts = mc.polyEvaluate(SkinModel, v=True)
56 | mc.skinPercent(SkinClusterNode, '%s.vtx[0:%s]'%(SkinModel, ModelVts), tv=(JointName, 0))
57 |
58 | #- set Weight Value
59 | for VtxID, WeightV in WeightDT.iteritems():
60 | mc.skinPercent(SkinClusterNode, '%s.vtx[%s]'%(SkinModel, VtxID), tv=(JointName, WeightV))
61 |
62 |
63 |
64 | def TransWeightToCluster():
65 | ModelName = mc.textField('ClusterModelFLD', q=True, tx=True)
66 | SkinModel = mc.textField('SkinModelFLD', q=True, tx=True)
67 | ClusterName = mc.textField('ClusterNameFLD', q=True, tx=True)
68 | JointName = mc.textField('JointNameFLD', q=True, tx=True)
69 | #- get the cluster Node Name..
70 | if mc.nodeType(ClusterName) == 'transform':
71 | ClusterName = mc.listConnections(ClusterName, t='cluster')[0]
72 | else:
73 | pass
74 |
75 | #- get SkinNode Name
76 | SkinClusterNode = mel.eval('findRelatedSkinCluster ' + SkinModel)
77 |
78 | #- set Value
79 | ModelVts = mc.polyEvaluate(SkinModel, v=True)
80 | JointID = mc.skinCluster(SkinClusterNode, q=True, inf=True).index(JointName)
81 | for i in range(ModelVts):
82 | SkinWeight = mc.skinPercent(SkinClusterNode, '%s.vtx[%s]'%(SkinModel, i), q=True, v=True)[JointID]
83 | mc.percent(ClusterName, '%s.vtx[%s]'%(ModelName, i), v=SkinWeight)
84 |
85 |
86 | #if __name__ == "__main__":TransWeight('pPlane1', 'cluster1Handle', 'joint1')
87 |
--------------------------------------------------------------------------------
/Plugcmds/SetDrivenKeysforToes.py:
--------------------------------------------------------------------------------
1 | import os, json
2 | import maya.cmds as mc
3 | from FoleyUtils import scriptTool, uiTool
4 |
5 |
6 | UIwndClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'SetDrivenKeysforToes.ui'))
7 | class SetDrivenKeyforToes(UIwndClass, baseClass):
8 | def __init__(self, parent=None):
9 | if uiTool.windowExists(parent, 'setDrivenKeyForToesWindow'):
10 | return
11 | super(SetDrivenKeyforToes, self).__init__(parent)
12 | self.setupUi(self)
13 | self.show()
14 | #-------------
15 |
16 |
17 | def setRange(self, Value, OldMin, OldMax, minV, maxV):
18 | OutValue = minV + (((Value-OldMin)/(OldMax-OldMin)) * (maxV-minV))
19 | return OutValue
20 |
21 |
22 |
23 | def on_actionSetkeys_triggered(self, clicked=None):
24 | if clicked==None:return
25 | if not os.path.exists('D:/toe.json'):return
26 | # open File
27 | f = open('D:/toe.json', 'r')
28 | ControlNameData = json.load(f)
29 | f.close()
30 |
31 | # get Axis
32 | Axis = 'ry'
33 | if self.axisXRDN.isChecked():
34 | Axis = 'rx'
35 | elif self.axisYRDN.isChecked():
36 | Axis = 'ry'
37 | else:
38 | Axis = 'rz'
39 |
40 | # get Value
41 | DvnMinValue = self.minFLD.value()
42 | DvnMaxValue = self.maxFLD.value()
43 |
44 | if self.reverseBOX.isChecked():
45 | Reverse = 1
46 | else:
47 | Reverse = -1
48 | #---
49 |
50 | print '-*-' * 20
51 | print '\n'
52 | for Driver, Drivens in ControlNameData.iteritems():
53 | if not mc.objExists(Driver):continue
54 | DriverMinV = mc.addAttr('%s.spread'%Driver, q=True, min=True)
55 | DriverMaxV = mc.addAttr('%s.spread'%Driver, q=True, max=True)
56 |
57 | Drivens = [x for i, x in enumerate(Drivens) if x not in Drivens[:i]]
58 | Counts = len(Drivens)
59 | for i, Driven in enumerate(Drivens):
60 | #- Driven Open
61 | mc.setDrivenKeyframe('%s.%s'%(Driven, Axis), cd='%s.spread'%Driver, dv=0, v=0)
62 | DrivenrotateV = self.setRange(i * 1.0, 0, Counts-1, DvnMaxValue*-1, DvnMaxValue)
63 | mc.setDrivenKeyframe('%s.%s'%(Driven, Axis), cd='%s.spread'%Driver, dv=DriverMaxV, v=DrivenrotateV * Reverse)
64 | #- Driven Close
65 | DrivenrotateV = self.setRange(i * 1.0, 0, Counts-1, DvnMinValue, DvnMinValue * -1)
66 | mc.setDrivenKeyframe('%s.%s'%(Driven, Axis), cd='%s.spread'%Driver, dv=DriverMinV, v=DrivenrotateV * -1 * Reverse)
67 |
68 | #--- output ---
69 | print 'cmds.setDrivenKeyframe("%s.%s", cd="%s.spread", dv=0, v=0)'%(Driven, Axis, Driver)
70 | print 'cmds.setDrivenKeyframe("%s.%s", cd="%s.spread", dv=%f, v=%f)'%(Driven, Axis, Driver, DriverMaxV, DrivenrotateV * Reverse)
71 | print 'cmds.setDrivenKeyframe("%s.%s", cd="%s.spread", dv=%f, v=%f)'%(Driven, Axis, Driver, DriverMinV, DrivenrotateV * -1 * Reverse)
72 |
73 | print '\n'
74 | print '-*-' * 20
75 |
76 | if self.deleteFilesCBX.isChecked():
77 | os.remove('D:/toe.json')
--------------------------------------------------------------------------------
/Plugcmds/findCoincidentGeometry/findCoincidentGeometry.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Thu, 20 Nov 2014 14:47:35
5 | #========================================
6 | import hashlib, pymel.core
7 | import maya.cmds as mc
8 | import maya.OpenMaya as OpenMaya
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 | def findCoincidentGeometrys():
11 | #- 1. get all of the polygeometry
12 | geometrys = dict.fromkeys(mc.listRelatives(mc.ls(type='mesh'), p=True, path=True)).keys()
13 |
14 | #- 2. find geometry bounds
15 | minX, minY, minZ, maxX, maxY, maxZ = 0, 0, 0, 0, 0, 0
16 | for geo in geometrys:
17 | bbmn = mc.getAttr('%s.bbmn'%geo)[0]
18 | bbmx = mc.getAttr('%s.bbmx'%geo)[0]
19 | minX = min(minX, bbmn[0])
20 | minY = min(minY, bbmn[1])
21 | minZ = min(minZ, bbmn[2])
22 | maxX = max(maxX, bbmx[0])
23 | maxY = max(maxY, bbmx[1])
24 | maxZ = max(maxZ, bbmx[2])
25 |
26 | #- defind ray point out of the geometrys
27 |
28 | # | - |<---------- . ---------->| - |
29 | xDis, yDis, zDis = abs(maxX - minX), abs(maxY - minY), abs(maxZ - minZ)
30 | minX = minX - xDis * 0.1
31 | minY = minY - yDis * 0.1
32 | minZ = minZ - xDis * 0.1
33 | maxX = maxX + xDis * 0.1
34 | maxY = maxY + yDis * 0.1
35 | maxZ = maxZ + zDis * 0.1
36 |
37 | # *A *B *C
38 | # \ | /
39 | # *D - * - *E
40 | # / | \
41 | # *F *G *H
42 | pointA = minX, minY, minZ
43 | pointB = minX, minY, maxZ
44 | pointC = minX, maxY, minZ
45 | pointD = minX, maxY, maxZ
46 | pointE = maxX, minY, minZ
47 | pointF = maxX, minY, maxZ
48 | pointG = maxX, maxY, minZ
49 | pointH = maxX, maxY, maxZ
50 | pointI = minX, (maxY + minY) / 2.0, (maxZ + minZ) / 2.0
51 | pointJ = maxX, (maxY + minY) / 2.0, (maxZ + minZ) / 2.0
52 | pointK = (maxX + minX) / 2.0, minY, (maxZ + minZ) / 2.0
53 | pointL = (maxX + minX) / 2.0, maxY, (maxZ + minZ) / 2.0
54 | pointM = (maxX + minX) / 2.0, (maxY + minY) / 2.0, minZ
55 | pointN = (maxX + minX) / 2.0, (maxY + minY) / 2.0, maxZ
56 |
57 | #- 3. find point on mesh from ray point
58 | geometryData = dict()
59 |
60 | outPoint = OpenMaya.MPoint()
61 | utilA = OpenMaya.MScriptUtil()
62 | utilB = OpenMaya.MScriptUtil()
63 | face = utilA.asIntPtr()
64 |
65 | for geo in geometrys:
66 | mMesh = OpenMaya.MFnMesh(pymel.core.PyNode(geo).__apiobject__())
67 |
68 | md5 = hashlib.md5()
69 | for p in (pointA, pointB, pointC, pointD, pointE, pointF, pointG, pointH, pointI, pointJ, pointK, pointL, pointM, pointN):
70 | mMesh.getClosestPoint(OpenMaya.MPoint(*p), outPoint, OpenMaya.MSpace.kWorld, face)
71 |
72 | faceId = utilB.getInt(face)
73 | md5.update('%d'%faceId)
74 |
75 | posi = mc.xform('%s.f[%d]'%(geo, faceId), q=True, ws=True, t=True)
76 | for ps in posi:
77 | md5.update('%f'%ps)
78 |
79 | geometryData.setdefault(md5.hexdigest(), list()).append(geo)
80 |
81 | #- 4. find coincident geometrys
82 | Result = list()
83 | for k, v in geometryData.iteritems():
84 | if len(v) < 2:
85 | continue
86 | Result.extend(v)
87 |
88 | #-
89 | return Result
--------------------------------------------------------------------------------
/Plugcmds/quickSetDrivenKey.py:
--------------------------------------------------------------------------------
1 | import os
2 | import maya.cmds as mc
3 | from FoleyUtils import scriptTool, uiTool, mayaTool
4 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
5 |
6 |
7 | UIClass, BaseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'quickSetDrivenKey.ui'))
8 |
9 | class QuickSetDrivenKey(UIClass, BaseClass):
10 | def __init__(self, parent=None):
11 | if uiTool.windowExists(parent, 'quickSetDrivenKeywindow'):
12 | return
13 |
14 | super(QuickSetDrivenKey, self).__init__(parent)
15 | self.setupUi(self)
16 | self.show()
17 |
18 |
19 | def _loadAttribute(self, LineEdit):
20 | SelectOBJ = mc.ls(sl=True)
21 | if len(SelectOBJ) == 0:return
22 |
23 | SelectAttriBute = mc.channelBox('mainChannelBox', q=True, sma=True)
24 | if SelectAttriBute == None:return
25 |
26 | LineEdit.setText('%s.%s'%(SelectOBJ[-1], SelectAttriBute[0]))
27 |
28 |
29 |
30 | def on_actionLoadDriverAttribute_triggered(self, args=None):
31 | if args==None:return
32 | self._loadAttribute(self.DriverAttributeLineEdit)
33 |
34 |
35 |
36 | def on_actionLoadDrivenAttribute_triggered(self, args=None):
37 | if args==None:return
38 | self._loadAttribute(self.DrivenAttributeLineEdit)
39 |
40 |
41 |
42 | def _setKeyFrame(self, DriverValueSpinbox, DrivenValueSpinbox):
43 | DriverAttibute = str(self.DriverAttributeLineEdit.text())
44 | DrivenAttibute = str(self.DrivenAttributeLineEdit.text())
45 | DriverValue = DriverValueSpinbox.value()
46 | DrivenValue = DrivenValueSpinbox.value()
47 |
48 | if len(DriverAttibute) == 0:return
49 | if len(DrivenAttibute) == 0:return
50 |
51 | mc.setDrivenKeyframe(DrivenAttibute, cd=DriverAttibute, dv=DriverValue, v=DrivenValue)
52 |
53 |
54 | @mayaTool.undo_decorator
55 | def on_actionKeyDriven1_triggered(self, args=None):
56 | if args==None:return
57 | self._setKeyFrame(self.DriverValueSpinbox1, self.DrivenValueSpinbox1)
58 |
59 |
60 | @mayaTool.undo_decorator
61 | def on_actionKeyDriven2_triggered(self, args=None):
62 | if args==None:return
63 | self._setKeyFrame(self.DriverValueSpinbox2, self.DrivenValueSpinbox2)
64 |
65 |
66 | @mayaTool.undo_decorator
67 | def on_actionKeyDriven3_triggered(self, args=None):
68 | if args==None:return
69 | self._setKeyFrame(self.DriverValueSpinbox3, self.DrivenValueSpinbox3)
70 |
71 |
72 | @mayaTool.undo_decorator
73 | def on_actionKeyDriven4_triggered(self, args=None):
74 | if args==None:return
75 | self._setKeyFrame(self.DriverValueSpinbox4, self.DrivenValueSpinbox4)
76 |
77 |
78 | @mayaTool.undo_decorator
79 | def on_actionKeyDriven5_triggered(self, args=None):
80 | if args==None:return
81 | self._setKeyFrame(self.DriverValueSpinbox5, self.DrivenValueSpinbox5)
82 |
83 |
84 | @mayaTool.undo_decorator
85 | def on_actionKeyDrivenAll_triggered(self, args=None):
86 | if args==None:return
87 | self.on_actionKeyDriven1_triggered(True)
88 | self.on_actionKeyDriven2_triggered(True)
89 | self.on_actionKeyDriven3_triggered(True)
90 | self.on_actionKeyDriven4_triggered(True)
91 | self.on_actionKeyDriven5_triggered(True)
--------------------------------------------------------------------------------
/Plugcmds/BlendIKFKoutputs.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as mc
2 | class CompIKFKoutput(object):
3 | prefsNode = 'prefs_grp'
4 | DriverDt = {
5 | 'leftArm':('L_armElbowFk_ctl_0.ry', 'L_armElbowIk_jnt_0.ry', 'L_armFkIk_ctl_0'),
6 | 'rightArm':('R_armElbowFk_ctl_0.ry', 'R_armElbowIk_jnt_0.ry', 'R_armFkIk_ctl_0'),
7 | 'leftLeg':('L_legKneeFk_ctl_0.rz', 'L_legKneeIk_jnt_0.rz', 'L_legFkIk_ctl_0'),
8 | 'rightLeg':('R_legKneeFk_ctl_0.rz', 'R_legKneeIk_jnt_0.rz', 'R_legFkIk_ctl_0')
9 | }
10 | part = ('leftArm','rightArm','leftLeg','rightLeg', 'leftAnkle', 'rightAnkle')
11 |
12 | def builde(self):
13 | if not mc.objExists(self.prefsNode):return
14 |
15 | #-> add Attr
16 | for compent in self.part:
17 | mc.addAttr(self.prefsNode, sn=compent, k=True)
18 | mc.setAttr('%s.%s'%(self.prefsNode, compent), 0, l=True)
19 | #mc.addAttr(self.prefsNode, sn='%smax'%compent, nn='max', min=0, max=360, dv=100, k=True)
20 | #mc.addAttr(self.prefsNode, sn='%sBlend'%compent, nn='blend', min=0, max=1, dv=0, k=True)
21 | mc.addAttr(self.prefsNode, sn='%soutput'%compent, nn='output', min=0, max=360, dv=0, k=True)
22 |
23 |
24 |
25 |
26 | for i, side in enumerate('LR'):
27 |
28 | RangeNode = mc.createNode('setRange')
29 | mc.setAttr('%s.oldMinY'%RangeNode, mc.getAttr('%s_legAnkle_bnd_0.rz'%side))
30 | mc.setAttr('%s.oldMaxY'%RangeNode, mc.getAttr('%s_legAnkle_bnd_0.rz'%side) + 360)
31 | mc.setAttr('%s.minY'%RangeNode, 0)
32 | mc.setAttr('%s.maxY'%RangeNode, 360)
33 | mc.connectAttr('%s_legAnkle_bnd_0.rz'%side, '%s.valueY'%RangeNode)
34 | mc.connectAttr('%s.oy'%RangeNode, '%s.%soutput'%(self.prefsNode, self.part[-2:][i]))
35 | mc.setAttr('%s.%soutput'%(self.prefsNode, self.part[-2:][i]), l=True)
36 |
37 | for compent, Joint in self.DriverDt.iteritems():
38 | if not mc.objExists(Joint[0]) or not mc.objExists(Joint[1]):return
39 |
40 | #-FK range
41 | #FKRange = mc.createNode('setRange')
42 | #mc.setAttr('%s.oldMinY'%FKRange, 0)
43 | #mc.setAttr('%s.oldMaxY'%FKRange, 0)
44 | #mc.setAttr('%s.minY'%FKRange, 0)
45 | #mc.setAttr('%s.maxY'%FKRange, 360)
46 | #mc.connectAttr(Joint[0], '%s.valueY'%FKRange)
47 |
48 |
49 | #-IK range
50 | IKRange = mc.createNode('setRange')
51 | mc.setAttr('%s.oldMinY'%IKRange, mc.getAttr(Joint[1]) - 360)
52 | mc.setAttr('%s.oldMaxY'%IKRange, mc.getAttr(Joint[1]) + 360)
53 | mc.setAttr('%s.minY'%IKRange, -360)
54 | mc.setAttr('%s.maxY'%IKRange, 360)
55 | mc.connectAttr(Joint[1], '%s.valueY'%IKRange)
56 |
57 |
58 | #-Blend
59 | BlendNode = mc.createNode('blendTwoAttr')
60 | mc.connectAttr('%s.FKIKBlend'%Joint[2], '%s.ab'%BlendNode)#mc.connectAttr('%s.%sBlend'%(self.prefsNode, compent), '%s.ab'%BlendNode)
61 | mc.connectAttr(Joint[0], '%s.input[0]'%BlendNode)
62 | mc.connectAttr('%s.oy'%IKRange, '%s.input[1]'%BlendNode)
63 |
64 |
65 | mc.connectAttr('%s.o'%BlendNode, '%s.%soutput'%(self.prefsNode, compent))
66 | mc.setAttr('%s.%soutput'%(self.prefsNode, compent), l=True)
67 |
68 | mc.select(self.prefsNode)
--------------------------------------------------------------------------------
/FoleyUtils/nameTool.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 25 Jun 2014 14:43:02
5 | #=============================================
6 | import re, os, string
7 | import maya.cmds as mc
8 |
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 |
11 | def compileWindowsFileName(fullPath):
12 | '''
13 | build a not exists windows file name...
14 | Exp:
15 | D:/text -> D:/text(1) -> D:/text(2) -> D:/text(3) ... D:/text(n+1)
16 | E:/Document.txt -> E:/Document(1).txt -> E:/Document(2).txt -> E:/Document(3).txt ... E:/Document(n+1).txt
17 | '''
18 | if not os.path.isfile(fullPath) and not os.path.isdir(fullPath):
19 | return fullPath
20 |
21 | fname, fextension = os.path.splitext(fullPath)
22 | res = re.search('\(\d+\)$', fname)
23 | if res:
24 | index = string.zfill(int(res.group()[1:-1]) + 1, len(res.group()) - 2)
25 | fname = re.sub('\(\d+\)$', '(%s)'%index, fname)
26 | else:
27 | fname = '%s(1)'%fname
28 | fullName = fname + fextension
29 |
30 | return compileWindowsFileName(fullName)
31 |
32 |
33 |
34 |
35 |
36 | def compileMayaObjectName(objectName):
37 | '''
38 | build a not exists maya object name...
39 | Exp:
40 | pCube -> pCube1 -> pCube2 -> pCube3 -> pCube4 ... pCuben+1
41 | pSphere -> pSphere1 -> pSphere2 -> pSphere3 -> pSphere4 ... pSpheren+1
42 | '''
43 | if not mc.objExists(objectName):
44 | return objectName
45 |
46 | res = re.search('\d+$', objectName)
47 | if res:
48 | index = string.zfill(int(res.group()) + 1, len(res.group()))
49 | result = re.sub('\d+$', index, objectName)
50 | else:
51 | result = '%s1'%(objectName)
52 |
53 | return compileMayaObjectName(result)
54 |
55 |
56 |
57 |
58 |
59 | def SerializationObjectNames(objectList, nameFormat='Temp*', start=0, padding=3):
60 | '''
61 | objectList must is a list or a tuple
62 | nameFormat mutst have one " * "
63 | Exp:
64 | [pCulbe, pCulbe1, pCulbe2, pCulbe3, pCulbe4] -> temp*
65 | -> [temp000, temp001, temp002, temp003, temp004]
66 |
67 | [pCulbe, pCulbe1, pCulbe2, pCulbe3, pCulbe4] -> C_temp*_geo_0
68 | -> [C_temp000_geo_0, C_temp001_geo_0, C_temp002_geo_0, C_temp003_geo_0, C_temp004_geo_0]
69 | '''
70 | if not isinstance(objectList, (list, tuple)):
71 | return
72 |
73 | if nameFormat.count('*') != 1:
74 | return
75 |
76 | newNameList = []
77 | for i, obj in enumerate(objectList):
78 | newName = compileMayaObjectName(nameFormat.replace('*', string.zfill(i + start, padding)))
79 | newNameList.append(newName)
80 | return newNameList
81 |
82 |
83 |
84 |
85 | def SerializationFileNames(path, nameFormat='Temp*', start=0, padding=3):
86 | if not os.path.isdir(path):
87 | return
88 |
89 | if nameFormat.count('*') != 1:
90 | return
91 |
92 | #- get files -
93 | files = os.listdir(path)
94 |
95 | for i, f in enumerate(files):
96 | #- build name
97 | fextension = os.path.splitext(f)[-1]
98 | NewName = nameFormat.replace('*', string.zfill(i + start, padding)) + fextension
99 | #- rename
100 | os.rename(os.path.join(path, f), compileWindowsFileName(os.path.join(path, NewName)))
--------------------------------------------------------------------------------
/Plugcmds/mirrorCtlShp.py:
--------------------------------------------------------------------------------
1 | import os.path, re
2 | import maya.cmds as mc
3 | from FoleyUtils import scriptTool, uiTool, mayaTool
4 |
5 |
6 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'mirrorCtlShp.ui'))
7 | class MirrorControlShp(windowClass, baseClass):
8 | def __init__(self, parent=None):
9 | if uiTool.windowExists(parent, 'mirrorControlShapeUI'):return
10 | super(MirrorControlShp, self).__init__(parent)
11 | self.setupUi(self)
12 | self.show()
13 |
14 |
15 | def on_btn_mirror_clicked(self, click=None):
16 | if click == None:return
17 | controlType = str(self.fld_controlType.text())
18 |
19 | flipAxis = 'X'
20 | if self.rdn_filpX.isChecked():
21 | flipAxis = 'X'
22 | elif self.rdn_filpY.isChecked():
23 | flipAxis = 'Y'
24 | else:
25 | flipAxis = 'Z'
26 |
27 |
28 | if self.rdn_lefttoright.isChecked():
29 | mirrorControlShape(controlType, 'L', 'R', flipAxis)
30 | else:
31 | mirrorControlShape(controlType, 'R', 'L', flipAxis)
32 |
33 |
34 |
35 |
36 | @mayaTool.undo_decorator
37 | def mirrorControlShape(typ, source, targent, flipAxis):
38 | if len(typ) == 0:return
39 | if source not in 'LR':return
40 | if source == targent:return
41 |
42 | #- get source side controls
43 | all_controls = ' '.join(mc.listRelatives(mc.ls(type='nurbsCurve'), p=True, path=True))
44 | matched_controls = re.findall('\S*%s_\w+_%s_\d+'%(source, typ), all_controls)
45 |
46 | for ctl in matched_controls:
47 | #- get targent control
48 | targentControl = re.sub('%s_'%source, '%s_'%targent, ctl)
49 | if not mc.objExists(targentControl):continue
50 |
51 | #- duplicate shape
52 | tempx = mc.duplicate(ctl, po=True)
53 | mc.parent(mc.listRelatives(ctl, s=True, path=True), tempx, s=True, add=True)
54 |
55 | #- make Temp
56 | Temp = mc.duplicate(tempx)[0]
57 | for a in 'trs':
58 | for b in 'xyz':
59 | attr = a + b
60 | mc.setAttr('%s.%s'%(Temp, attr), l=False, k=True, cb=False)
61 |
62 | #- close max min value controler
63 | mc.transformLimits(Temp, etx=(0, 0),ety=(0, 0),etz=(0, 0),erx=(0, 0),ery=(0, 0),erz=(0, 0))
64 | Temp = mc.parent(Temp, w=True)
65 |
66 | #- filp
67 | grp = mc.createNode('transform')
68 |
69 | sourcePosi = mc.xform(ctl, q=True, ws=True, rp=True)
70 | targenPosi = mc.xform(targentControl, q=True, ws=True, rp=True)
71 |
72 | midPoint = [(sourcePosi[0] + targenPosi[0]) / 2,
73 | (sourcePosi[0] + targenPosi[0]) / 2,
74 | (sourcePosi[0] + targenPosi[0]) / 2]
75 | mc.move(midPoint[0], midPoint[1], midPoint[2], grp, a=True)
76 |
77 |
78 | Temp = mc.parent(Temp, grp)
79 | mc.setAttr('%s.s%s'%(grp, flipAxis.lower()), -1)
80 |
81 | #- freeze transformations
82 | Temp = mc.parent(Temp, targentControl)
83 | mc.makeIdentity(Temp, apply=True, t=True, r=True, s=True)
84 |
85 | #- get original shapes
86 | originalShapes = mc.listRelatives(targentControl, s=True, path=True)
87 |
88 | #- parent new shapes
89 | shapes = mc.listRelatives(Temp, s=True, path=True)
90 | for shp in shapes:
91 | mc.setAttr('%s.ovc'%shp, mc.getAttr('%s.ovc'%originalShapes[0]))
92 | mc.parent(shapes, targentControl, s=True, r=True)
93 | for shp in shapes:
94 | mc.rename(shp, '%sShape'%targentControl)
95 |
96 | #- delete temp
97 | mc.delete(tempx, Temp, grp, originalShapes)
98 |
99 |
--------------------------------------------------------------------------------
/FoleyUtils/publishTool.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 25 Jun 2014 14:43:02
5 | #=============================================
6 | import string, os, re
7 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
8 |
9 | VERSION_PADDING = 3
10 |
11 | def conformFilePath(path, MSC='maya'):
12 | '''
13 | maya: E:/a\b/c\qq.ma -> E:/a/b/c/qq.ma
14 | windows: E:/a\b/c\qq.ma -> E:\a\b\c\qq.ma
15 | '''
16 | if MSC == 'maya':
17 | newPath = path.replace('\\', '/')
18 | else:
19 | newPath = path.replace('/', '\\')
20 | return newPath
21 |
22 |
23 |
24 |
25 | def getVersionsFiles(path, fextension=''):
26 | '''
27 | get files dictionary..
28 | '''
29 | fileDict = {}
30 | if not os.path.isdir(path):
31 | return fileDict
32 |
33 | files = re.findall('([^\|]+((?<=v)\d+(?=\.%s))[^\|]+)'%fextension, string.join(os.listdir(path), '|'))
34 | for f, v in files:
35 | fileDict[v] = conformFilePath(os.path.join(path, f))
36 |
37 | return fileDict
38 |
39 |
40 |
41 |
42 | def getVersions(path, fextension=''):
43 | '''
44 | get all of versions..
45 | '''
46 | versions = getVersionsFiles(path, fextension).keys()
47 | versions.sort()
48 | return versions
49 |
50 |
51 |
52 |
53 |
54 | def getLastVersion(path, fextension=''):
55 | '''
56 | get the last version..
57 | '''
58 | versions = getVersions(path, fextension)
59 | versions.insert(0, 0)
60 |
61 | lastVersion = max([int(v) for v in versions])
62 | lastVersion = string.zfill(lastVersion, VERSION_PADDING)
63 | return lastVersion
64 |
65 |
66 |
67 |
68 | def getNewVersion(path, fextension=''):
69 | '''
70 | get the new version..
71 | '''
72 | lastVersion = int(getLastVersion(path, fextension))
73 | newVersion = string.zfill(lastVersion+1, VERSION_PADDING)
74 | return newVersion
75 |
76 |
77 |
78 |
79 | def getVersiondFile(path, version, fextension=''):
80 | '''
81 | get the last file fullpath by input version..
82 | '''
83 | fileDict = getVersionsFiles(path, fextension)
84 | filePath = fileDict.get(version, '')
85 | return filePath
86 |
87 |
88 |
89 |
90 | def getLastFile(path, fextension=''):
91 | '''
92 | get the last file fullpath..
93 | '''
94 | lastVersion = getLastVersion(path, fextension)
95 | lastFile = getVersiondFile(path, lastVersion, fextension)
96 | return lastFile
97 |
98 |
99 |
100 |
101 | def getNewFile(path, fname_format='name_v*', fextension=''):
102 | '''
103 | build a new version file...
104 | '''
105 | filePath = ''
106 | lastFile = getLastFile(path, fextension)
107 | if not os.path.isfile(lastFile):
108 | filePath = conformFilePath(os.path.join(path, fname_format.replace('*', string.zfill(1, VERSION_PADDING))))
109 |
110 | else:
111 | lastVersion = getLastVersion(path, fextension)
112 | newVersion = getNewVersion(path, fextension)
113 |
114 | fname, fextension = os.path.splitext(lastFile)
115 | filePath = re.sub('%s$'%lastVersion, newVersion, fname) + fextension
116 |
117 | return filePath
118 |
119 |
120 |
121 |
122 | def getSize(path):
123 | '''
124 | return a file or a dir size by bytes...
125 | '''
126 | size = 0
127 | if os.path.isfile(path):
128 | size = os.path.getsize(path)
129 |
130 | elif os.path.isdir(path):
131 | for p, d, fs in os.walk(path):
132 | for f in fs:
133 | size += os.path.getsize(os.path.join(p, f))
134 | return size
--------------------------------------------------------------------------------
/Plugcmds/MirrorClusterWeights/MirrorClusterWeights.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Thu, 16 Oct 2014 10:31:59
5 | #========================================
6 | import os.path
7 | from FoleyUtils import scriptTool, uiTool
8 | import maya.cmds as mc
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 | baseClass, windowClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'clusterWeightsUI.ui'))
11 | class ClusterWeightsUI(baseClass, windowClass):
12 | def __init__(self, parent=None):
13 | if uiTool.windowExists(parent, 'MirrorClusterWindow'):
14 | return
15 | super(ClusterWeightsUI, self).__init__(parent)
16 | self.setupUi(self)
17 | self.show()
18 |
19 |
20 | def on_btn_Geometry_clicked(self, args=None):
21 | if args == None:return
22 | sel = mc.ls(sl=True)
23 | if len(sel) < 1:return
24 | if not mc.listRelatives(sel[0], s=True, type='mesh'):return
25 | self.let_Geometry.setText(sel[0])
26 |
27 |
28 | def on_btn_Source_clicked(self, args=None):
29 | if args == None:return
30 | sel = mc.ls(sl=True)
31 | if len(sel) < 1:return
32 | if mc.nodeType(sel[0]) == 'cluster':
33 | self.let_Source.setText(sel[0])
34 | elif mc.listRelatives(sel[0], s=True, type='clusterHandle'):
35 | self.let_Source.setText(mc.listConnections(sel[0])[0])
36 | else:
37 | return
38 |
39 |
40 | def on_btn_Targent_clicked(self, args=None):
41 | if args == None:return
42 | sel = mc.ls(sl=True)
43 | if len(sel) < 1:return
44 | if mc.nodeType(sel[0]) == 'cluster':
45 | self.let_Targent.setText(sel[0])
46 | elif mc.listRelatives(sel[0], s=True, type='clusterHandle'):
47 | self.let_Targent.setText(mc.listConnections(sel[0])[0])
48 | else:
49 | return
50 |
51 | def on_btn_Mirror_clicked(self, args=None):
52 | if args == None:return
53 | geo = str(self.let_Geometry.text())
54 | src = str(self.let_Source.text())
55 | dst = str(self.let_Targent.text())
56 |
57 | if not mc.objExists(geo):
58 | return
59 | if not mc.objExists(src):
60 | return
61 | if not mc.objExists(dst):
62 | return
63 |
64 | infoNode = mc.createNode('closestPointOnMesh')
65 | shape = mc.listRelatives(geo, s=True, path=True, type='mesh')[0]
66 | mc.connectAttr('%s.outMesh'%shape, '%s.inMesh'%infoNode)
67 |
68 | srcWeightListIndex = mc.listRelatives(mc.cluster(src, q=True, g=True), p=True, path=True).index(geo)
69 | dstWeightListIndex = mc.listRelatives(mc.cluster(dst, q=True, g=True), p=True, path=True).index(geo)
70 |
71 | vtxCounts = len(mc.ls('%s.vtx[*]'%geo, fl=True))
72 | srcValues = mc.getAttr('%s.wl[%d].w[:%d]'%(src, srcWeightListIndex, vtxCounts-1))
73 | dstValues = []
74 |
75 | self.progressBar.setMaximum(vtxCounts)
76 | for i, vtx in enumerate(mc.ls('%s.vtx[*]'%geo, fl=True)):
77 | postions = mc.xform(vtx, q=True, ws=True, t=True)
78 |
79 | mc.setAttr('%s.ipx'%infoNode, postions[0] * -1)
80 | mc.setAttr('%s.ipy'%infoNode, postions[1] * 1)
81 | mc.setAttr('%s.ipz'%infoNode, postions[2] * 1)
82 |
83 | dstValues.append(srcValues[mc.getAttr('%s.vt'%infoNode)])
84 | #-
85 | self.progressBar.setValue(i)
86 |
87 | mc.setAttr('%s.wl[%d].w[:%d]'%(dst, dstWeightListIndex, len(dstValues)-1), *dstValues)
88 | mc.delete(infoNode)
89 | #-
90 | self.progressBar.setMaximum(1)
91 | self.progressBar.setValue(0)
--------------------------------------------------------------------------------
/Plugcmds/TransWeights/TransWeights.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Tue, 16 Sep 2014 15:31:44
5 | #========================================
6 | import os.path, tempfile
7 | import maya.cmds as mc
8 | from PyQt4 import QtGui
9 | from FoleyUtils import scriptTool, uiTool, mayaTool
10 | from rigBuilder import rigUtils
11 | from rigBuilder.body import bodyIO
12 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
13 |
14 | def getSkinClusterByJoint(geometry, Joint):
15 | skincluster = mayaTool.findSkinCluster(geometry)
16 | influcences = mc.skinCluster(skincluster, q=True, inf=True)
17 | vtxCount = mc.polyEvaluate(geometry, v=True)
18 | index = influcences.index(Joint)
19 | weights = []
20 | for i in range(vtxCount):
21 | weights.append(mc.skinPercent(skincluster, '%s.vtx[%d]'%(geometry, i), q=True, v=True)[index])
22 | return weights
23 |
24 |
25 | def setSkinCluster(geometry, Joint, weights):
26 | skincluster = mayaTool.findSkinCluster(geometry)
27 | for i, w in enumerate(weights):
28 | mc.skinPercent(skincluster, '%s.vtx[%d]'%(geometry, i), tv=(Joint, w))
29 |
30 |
31 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'TransWeights.ui'))
32 | class TransWeightsUI(windowClass, baseClass):
33 | def __init__(self, parent=uiTool.getMayaWindow()):
34 | if uiTool.windowExists(parent, 'TransWeightsUI'):
35 | return
36 | #---------------------------------------------------------------------------------------------------
37 | super(TransWeightsUI, self).__init__(parent)
38 | self.setupUi(self)
39 |
40 | self.btn_LoadSkin.setIcon(QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'load.png')))
41 | self.btn_LoadJoint.setIcon(QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'load.png')))
42 | self.btn_Export.setIcon(QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'export.png')))
43 | self.btn_Import.setIcon(QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'import.png')))
44 |
45 | self.show()
46 | #---------------------------------------------------------------------------------------------------
47 | self.__data = []
48 |
49 | def on_btn_LoadSkin_clicked(self, args=None):
50 | if args == None:return
51 | sel = mc.ls(sl=True, type='transform')
52 | if len(sel) < 1:
53 | return
54 | self.lineEdit_Geometry.setText(sel[0])
55 |
56 |
57 | def on_btn_LoadJoint_clicked(self, args=None):
58 | if args == None:return
59 | sel = mc.ls(sl=True, type='joint')
60 | if len(sel) < 1:
61 | return
62 | self.lineEdit_Joint.setText(sel[0])
63 |
64 |
65 | def on_btn_Export_clicked(self, args=None):
66 | if args == None:return
67 | geometry = str(self.lineEdit_Geometry.text())
68 | Joint = str(self.lineEdit_Joint.text())
69 | if not mc.objExists(geometry):
70 | return
71 | if not mc.objExists(Joint):
72 | return
73 | #-
74 | self.__data = getSkinClusterByJoint(geometry, Joint)
75 | #-
76 | self.lineEdit_Geometry.setStyleSheet('color: rgb(255, 255, 127);')
77 | self.lineEdit_Joint.setStyleSheet('color: rgb(255, 255, 127);')
78 |
79 |
80 | def on_btn_Import_clicked(self, args=None):
81 | if args == None:return
82 |
83 | geometry = str(self.lineEdit_Geometry.text())
84 | Joint = str(self.lineEdit_Joint.text())
85 |
86 | setSkinCluster(geometry, Joint, self.__data)
87 | self.__data = []
88 |
89 | self.lineEdit_Geometry.setStyleSheet('')
90 | self.lineEdit_Joint.setStyleSheet('')
--------------------------------------------------------------------------------
/Plugcmds/inspectScene/inspectScene.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Fri, 24 Oct 2014 10:45:39
5 | #========================================
6 | import string, re, os.path
7 | import maya.cmds as mc
8 | from FoleyUtils import scriptTool, uiTool
9 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
10 |
11 | UIwndClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'inspectScene.ui'))
12 | class InspectSceneUI(UIwndClass, baseClass):
13 |
14 | def __init__(self, parent=None):
15 | if uiTool.windowExists(parent, 'inspectSceneWindow'):
16 | return
17 |
18 | super(InspectSceneUI, self).__init__(parent)
19 | self.setupUi(self)
20 | self.show()
21 | #-------------
22 |
23 |
24 | def on_actionInspectScene_triggered(self, *agrs):
25 | if not agrs:return
26 | self.DuplacatesNamesOBJ = InspectScene.inspectDuplicatesNames()
27 | self.NoFreeGeometeys = InspectScene.inspectGeometryAttributes()
28 | self.DuplicatesShapesOBJ = InspectScene.insepectDuplicatesShapes()
29 |
30 | #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
31 | def _readResult(OBJList, Field, Button):
32 | if len(OBJList) > 0:
33 | Button.setEnabled(True)
34 | Field.setValue(len(OBJList))
35 | Field.setStyleSheet('color: rgb(255, 90, 90)')
36 | else:
37 | Button.setDisabled(True)
38 | Field.setValue(0)
39 | Field.setStyleSheet('')
40 |
41 | #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
42 | _readResult(self.DuplacatesNamesOBJ, self.fldDuplicatesnames, self.btnSelectDuplicatesnames)
43 | _readResult(self.NoFreeGeometeys, self.fldNoFreezeGeometeys, self.btnSelectNoFreezeGeometeys)
44 | _readResult(self.DuplicatesShapesOBJ, self.fldDuplicatesShapes, self.btnSelectDuplicatesShapes)
45 | #-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
46 |
47 |
48 | def on_actionSelectDuplicatesnames_triggered(self, *agrs):
49 | if not agrs:return
50 | mc.select(self.DuplacatesNamesOBJ)
51 |
52 |
53 |
54 | def on_actionSelectNoFreezeGeometeys_triggered(self, *agrs):
55 | if not agrs:return
56 | mc.select(self.NoFreeGeometeys)
57 |
58 |
59 |
60 | def on_actionSelectDuplicatesShapes_triggered(self, *agrs):
61 | if not agrs:return
62 | mc.select(self.DuplicatesShapesOBJ)
63 |
64 |
65 |
66 |
67 | class InspectScene(object):
68 |
69 | @classmethod
70 | def inspectDuplicatesNames(self):
71 | transforms = string.join(mc.ls(type='transform'))
72 | Duplicatesnames = re.findall('\S+\|+\S+', transforms)
73 | return Duplicatesnames
74 |
75 |
76 | @classmethod
77 | def inspectGeometryAttributes(self):
78 | geometrys = mc.listRelatives(mc.ls(type='mesh'), p=True, path=True)
79 | u_geometrys = []
80 | for geo in geometrys:
81 | Values = []
82 | for attr in ('tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz'):
83 | Values.append(mc.getAttr('%s.%s'%(geo, attr)))
84 | if sum(Values) == 3 and Values[-3:] == [1, 1, 1]:continue
85 | u_geometrys.append(geo)
86 |
87 | return u_geometrys
88 |
89 |
90 | @classmethod
91 | def insepectDuplicatesShapes(self):
92 | geometrys = mc.listRelatives(mc.ls(type=('mesh', 'nurbsSurface')), p=True, path=True)
93 | u_geometrys = []
94 | for geo in geometrys:
95 | if len(mc.listRelatives(geo, s=True)) > 1:
96 | u_geometrys.append(geo)
97 | return u_geometrys
--------------------------------------------------------------------------------
/Plugcmds/ReplaceUV/replaceUV.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | replaceUVwindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 317
10 | 484
11 |
12 |
13 |
14 | Replace Model UV
15 |
16 |
17 |
18 | -
19 |
20 |
21 | 2
22 |
23 |
-
24 |
25 |
26 |
27 | 0
28 | 25
29 |
30 |
31 |
32 |
33 | 16777215
34 | 25
35 |
36 |
37 |
38 |
39 | 10
40 |
41 |
42 |
43 |
44 | -
45 |
46 |
47 |
48 | 0
49 | 25
50 |
51 |
52 |
53 |
54 | 16777215
55 | 25
56 |
57 |
58 |
59 |
60 | 10
61 |
62 |
63 |
64 | Search
65 |
66 |
67 |
68 |
69 |
70 | -
71 |
72 |
73 |
74 | 10
75 |
76 |
77 |
78 | true
79 |
80 |
81 |
82 | -
83 |
84 |
85 | 2
86 |
87 |
-
88 |
89 |
90 |
91 | 16777215
92 | 6
93 |
94 |
95 |
96 | QProgressBar{
97 | border:1px solid rgb(191, 191, 191);
98 | border-radius:3px;
99 | }
100 |
101 | QProgressBar::chunk{
102 |
103 | background-color: rgb(191, 191, 191);
104 | }
105 |
106 |
107 |
108 | 1
109 |
110 |
111 | 0
112 |
113 |
114 | false
115 |
116 |
117 |
118 | -
119 |
120 |
121 |
122 | 10
123 |
124 |
125 |
126 | Replace
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/Plugcmds/makeAttachJoints/makeAttachJoints.py:
--------------------------------------------------------------------------------
1 | import os, inspect
2 | import maya.cmds as mc
3 | from FoleyUtils import scriptTool, uiTool
4 |
5 |
6 | def makePathJoints(basePathCus, UppathCus, JointCounts=5, uValuezerotoone=False):
7 | '''
8 | make joints attach to path..
9 | '''
10 | #--------------------------
11 | def _Attach(pathCus, attactOBJ, uValue, UpperOBJ=None, uValuezerotoone=False):
12 | CusShape = mc.listRelatives(pathCus, s=True, type='nurbsCurve')
13 | motionpathNode = mc.createNode('motionPath')
14 |
15 | # connect curve and motionpath node..
16 | mc.connectAttr(CusShape[0] + '.worldSpace[0]', motionpathNode + '.geometryPath')
17 | # connect motionpath node and object..
18 | for outAttr, inAttr in (('.rotateOrder', '.rotateOrder'),('.rotate', '.rotate'),('.allCoordinates', '.translate')):
19 | mc.connectAttr(motionpathNode + outAttr, attactOBJ + inAttr)
20 |
21 | # set Uvalue..
22 | mc.setAttr(motionpathNode + '.uValue', uValue)
23 |
24 |
25 | # set offset..
26 | if uValuezerotoone:
27 | mc.setAttr(motionpathNode + '.fractionMode', 1)
28 |
29 |
30 | # set upvector..
31 | if not UpperOBJ:return
32 | mc.setAttr(motionpathNode + '.worldUpType', 1)
33 | mc.connectAttr(UpperOBJ + '.worldMatrix[0]', motionpathNode + '.worldUpMatrix')
34 | mc.setAttr(motionpathNode + '.frontAxis', 0)
35 | mc.setAttr(motionpathNode + '.upAxis', 2)
36 |
37 | #--------------------------
38 | for i in range(JointCounts):
39 | mc.select(cl=True)
40 |
41 | Jnt = mc.joint(p=(0, 0, 0))
42 | Loc = mc.spaceLocator(p=(0, 0, 0))[0]
43 | uValue = 0.0
44 |
45 | if not uValuezerotoone:
46 | uValue = i
47 | else:
48 | uValue = (float(i) - 0) / (float(JointCounts - 1) - 0) * (1.0 - 0.0) + 0.0
49 |
50 | _Attach(UppathCus, Loc, uValue, None, uValuezerotoone)
51 | _Attach(basePathCus, Jnt, uValue, Loc, uValuezerotoone)
52 |
53 |
54 |
55 |
56 | UIwndClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'makeAttachJoints.ui'))
57 | class makeAttachJoints(UIwndClass, baseClass):
58 | def __init__(self, parent=None):
59 | if uiTool.windowExists(parent, 'makeAttachJointsWindow'):
60 | return
61 |
62 | super(makeAttachJoints, self).__init__(parent)
63 | self.setupUi(self)
64 | self.show()
65 | #-------------
66 |
67 |
68 | def on_actionLoadBaseCurve_triggered(self, clicked=None):
69 | if clicked==None:return
70 | SelOBJ = mc.ls(sl=True)
71 | if len(SelOBJ) == 1:
72 | self.BaseCusFLD.setText(SelOBJ[0])
73 | else:
74 | print '> > > you must select onlyone curve ! ! !',
75 |
76 |
77 | def on_actionLoadUpCurve_triggered(self, clicked=None):
78 | if clicked==None:return
79 | SelOBJ = mc.ls(sl=True)
80 | if len(SelOBJ) == 1:
81 | self.UpCusFLD.setText(SelOBJ[0])
82 | else:
83 | print '> > > you must select onlyone curve ! ! !',
84 |
85 |
86 | def on_minmaxRDN_toggled(self, args=None):
87 | if not args:return
88 | baseCurve = str(self.BaseCusFLD.text())
89 | if not mc.objExists(baseCurve):return
90 | self.CountsFLD.setValue(len(mc.ls('%s.cv[0:%d]'%(baseCurve, self.CountsFLD.maximum()), fl=True)))
91 |
92 |
93 | def on_actionMakeJoints_triggered(self, clicked=None):
94 | if clicked==None:return
95 | baseCurve = str(self.BaseCusFLD.text())
96 | upperCurve = str(self.UpCusFLD.text())
97 | jointCounts = self.CountsFLD.value()
98 | zeroToOne = self.zerotooneRDN.isChecked()
99 |
100 | # test...
101 | if len(baseCurve) < 1:return
102 | if len(upperCurve) < 1:return
103 | if jointCounts < 1:return
104 | # make...
105 | makePathJoints(baseCurve, upperCurve, jointCounts, zeroToOne)
--------------------------------------------------------------------------------
/Plugcmds/old/nameTool.py:
--------------------------------------------------------------------------------
1 | import os, inspect, rigToolUtils
2 | from PyQt4 import uic
3 | import maya.cmds as mc
4 |
5 | def getScriptPath():
6 | initfile = inspect.getfile(inspect.currentframe())
7 | initdir = os.path.dirname(initfile)
8 | return initdir
9 |
10 | #---------------------------------------------------------------------------------------------------------------
11 |
12 | Uiwnd, UiClass = uic.loadUiType(os.path.join(getScriptPath(), 'nameTool.ui'))
13 | class NameTool(Uiwnd, UiClass):
14 | def __init__(self, PntWnd = None):
15 | super(NameTool, self).__init__(PntWnd)
16 | self.setupUi(self)
17 | self.ReplaceInputField.setVisible(False)
18 | self.show()
19 |
20 | #---------------------------------------
21 | self.insertPs = 0
22 | self.maxLen = 0
23 | self.OBJList = []
24 | self.selOBJList = []
25 | #---------------------------------------
26 | def on_actionRefreshList_triggered(self, agrs=None):
27 | if agrs == None:return
28 | self.listWidget.clear()
29 | prefixString = str(self.lineEdit.text())
30 | replaceString = str(self.ReplaceInputField.text())
31 | for item in self.OBJList:
32 | realname = item.split('|')[-1]
33 | self.maxLen = max(len(realname), self.maxLen)
34 | displayName = realname
35 | if self.radioButton_Prefix.isChecked():
36 | displayName = '%s%s%s'%(realname[:self.insertPs], prefixString, realname[self.insertPs:])
37 | else:
38 | displayName = realname.replace(prefixString, replaceString)
39 | self.listWidget.addItem(displayName)
40 |
41 |
42 |
43 | def on_actionLoadOBJ_triggered(self, agrs=None):
44 | if agrs == None:return
45 | #---------------------------------------
46 | self.insertPs = 0
47 | self.maxLen = 0
48 | self.OBJList = []
49 | self.selOBJList = []
50 | #---------------------------------------
51 | self.selOBJList = mc.ls(sl=True)
52 | if len(self.selOBJList) == 0:return
53 |
54 | for OBJ in self.selOBJList:
55 | self.OBJList.append(OBJ)
56 | if not self.radioButton_Herarchy.isChecked():continue
57 | self.OBJList.extend(mc.listRelatives(OBJ, ad=True, path=True, type='transform') or [])
58 | self.on_actionRefreshList_triggered(True)
59 | #---------------------------------------
60 |
61 |
62 |
63 | def on_actionToTop_triggered(self, agrs=None):
64 | if agrs == None:return
65 | self.insertPs = 0
66 | self.on_actionRefreshList_triggered(True)
67 |
68 |
69 |
70 | def on_actionToEnd_triggered(self, agrs=None):
71 | if agrs == None:return
72 | self.insertPs = self.maxLen
73 | self.on_actionRefreshList_triggered(True)
74 |
75 |
76 |
77 | def on_actionToLeft_triggered(self, agrs=None):
78 | if agrs == None:return
79 | if self.insertPs <= 0:return
80 | self.insertPs -= 1
81 | self.on_actionRefreshList_triggered(True)
82 |
83 |
84 |
85 | def on_actionToRight_triggered(self, agrs=None):
86 | if agrs == None:return
87 | if self.insertPs >= self.maxLen:return
88 | self.insertPs += 1
89 | self.on_actionRefreshList_triggered(True)
90 |
91 |
92 | @rigToolUtils.undo_decorator
93 | def on_actionRename_triggered(self, agrs=None):
94 |
95 | if agrs == None:return
96 | if len(self.OBJList) == 0:return
97 | mc.select(self.OBJList)
98 | for i in range(len(self.OBJList)):
99 | oldName = self.OBJList[i]
100 | if not mc.objExists(oldName):
101 | oldName = mc.ls(sl=True)[i]
102 | newName = str(self.listWidget.item(i).text())
103 | mc.rename(oldName, newName)
104 | mc.select(cl=True)
105 | #---------------------------------------
106 | self.insertPs = 0
107 | self.maxLen = 0
108 | self.OBJList = []
109 | self.selOBJList = []
110 | self.listWidget.clear()
111 | #---------------------------------------
112 |
113 |
114 | if __name__ == "__main__":NameTool()
--------------------------------------------------------------------------------
/Plugcmds/makeRotateInfo.py:
--------------------------------------------------------------------------------
1 | import maya.cmds as mc
2 | import math
3 |
4 | def makeRotateInfo():
5 | selJoints = mc.ls(sl=True, type='joint')
6 | for Jnt in selJoints:
7 | makeRotateInfoForOneJoint(Jnt)
8 |
9 |
10 | def makeRotateInfoForOneJoint(joint):
11 | #- create sets
12 | TempCircle = mc.circle(r=1, ch=False)
13 | TempLine = mc.curve(d=1, p=((-1, 1, 0), (-1, -1, 0), (1, -1, 0), (1, 1, 0), (-1, 1, 0)))
14 |
15 | BaseLoc = mc.spaceLocator(p=(0,0,0), name='%s_RIF_Baseloc'%joint.rsplit('_', 2)[0])[0]
16 | AimLoc = mc.spaceLocator(p=(0,0,0), name='%s_RIF_aimLoc'%joint.rsplit('_', 2)[0])[0]
17 |
18 | grp = mc.group(TempCircle, TempLine, BaseLoc, AimLoc, name='%s_RIF_G'%joint.rsplit('_', 2)[0])
19 |
20 | #- set Temp Curve Template
21 | for temp in (TempCircle, TempLine):
22 | shape = mc.listRelatives(temp, s=True, path=True)
23 | mc.setAttr('%s.ove'%shape[0], 1)
24 | mc.setAttr('%s.ovdt'%shape[0], 1)
25 |
26 | #- lock attributes
27 | for attr in mc.listAttr(BaseLoc, k=True):
28 | if attr in ('translateX', 'translateY'):
29 | continue
30 | mc.setAttr('%s.%s'%(BaseLoc, attr), l=True, k=False)
31 |
32 | #- limit Translate
33 | mc.transformLimits(BaseLoc, tx=(-1, 1), ty=(-1, 1), etx=(True, True), ety=(True, True))
34 | mc.pointConstraint(AimLoc, BaseLoc, skip='z')
35 |
36 |
37 | #- add Atributes
38 | for attr in ('x', 'y', 'ypxp', 'ypxn', 'ynxp', 'ynxn', 'up', 'down', 'left', 'right'):
39 | mc.addAttr(grp, sn=attr, k=True)
40 |
41 | #- comp connections
42 | #- 1
43 | mc.connectAttr('%s.tx'%BaseLoc, '%s.x'%grp)
44 | mc.connectAttr('%s.ty'%BaseLoc, '%s.y'%grp)
45 |
46 | #- 2
47 | Values = ('ypxp', 0.707,0.707), ('ypxn', -0.707,0.707), ('ynxp', 0.707,-0.707), ('ynxn', -0.707,-0.707)
48 | for Attr, x, y in Values:
49 | node = mc.createNode('multDoubleLinear')
50 | mc.setDrivenKeyframe('%s.i1'%node, cd='%s.tx'%BaseLoc, dv=0, v=0, itt='linear', ott='linear')
51 | mc.setDrivenKeyframe('%s.i1'%node, cd='%s.tx'%BaseLoc, dv=x, v=1, itt='linear', ott='linear')
52 | mc.setDrivenKeyframe('%s.i2'%node, cd='%s.ty'%BaseLoc, dv=0, v=0, itt='linear', ott='linear')
53 | mc.setDrivenKeyframe('%s.i2'%node, cd='%s.ty'%BaseLoc, dv=y, v=1, itt='linear', ott='linear')
54 | mc.connectAttr('%s.o'%node, '%s.%s'%(grp, Attr))
55 |
56 | #- 3
57 | # to line 71
58 |
59 | #- match Position
60 | mc.delete(mc.parentConstraint(joint, grp))
61 | JntChildren = mc.listRelatives(joint, c=True, path=True, type='joint')
62 | if not JntChildren:return
63 | mc.delete(mc.aimConstraint(JntChildren, grp, aim=(0,0,1), u=(0,1,0)))
64 | mc.delete(mc.pointConstraint(JntChildren, AimLoc))
65 | mc.parentConstraint(joint, AimLoc, mo=True)
66 |
67 | #- match Scale
68 | startPosi = mc.xform(grp, q=True, ws=True, rp=True)
69 | endPosi = mc.xform(AimLoc , q=True, ws=True, rp=True)
70 | Dis = math.sqrt((startPosi[0] - endPosi[0]) ** 2 + (startPosi[1] - endPosi[1]) ** 2 + (startPosi[2] - endPosi[2]) ** 2)
71 | mc.setAttr(grp + '.sx', Dis)
72 | mc.setAttr(grp + '.sy', Dis)
73 | mc.setAttr(grp + '.sz', Dis)
74 |
75 |
76 | #- connect line 52
77 | Expstrings = '\
78 | $Ah = %s.ty;\n\
79 | $Aw = %s.tx;\n\
80 | $C = %s;\n\
81 | %s.%s = clamp(0, 180, 90 - acos($Ah / $C) * 180 / 3.14159265359);\n\
82 | %s.%s = clamp(-180, 0, 90 - acos($Ah / $C) * 180 / 3.14159265359);\n\
83 | %s.%s = clamp(0, 180, 90 - acos($Aw / $C) * 180 / 3.14159265359);\n\
84 | %s.%s = clamp(-180, 0, 90 - acos($Aw / $C) * 180 / 3.14159265359);\n\
85 | '%(BaseLoc, BaseLoc, mc.getAttr('%s.tz'%AimLoc), grp, 'up', grp, 'down', grp, 'left', grp, 'right')
86 | mc.expression(s=Expstrings)
87 | #---------------------------------------------------------------------------------------
88 |
89 |
90 |
91 | # connect attbutes to prefs_grp
92 | if not mc.objExists('prefs_grp'):return
93 | typ = joint.rsplit('_', 2)[0]
94 | mc.addAttr('prefs_grp', sn=typ, k=True)
95 | mc.setAttr('prefs_grp.' + typ, l=True)
96 | for Attr in mc.listAttr(grp, ud=True):
97 | mc.addAttr('prefs_grp', sn=typ + Attr, k=True)
98 | mc.connectAttr('%s.%s'%(grp, Attr), 'prefs_grp.%s%s'%(typ , Attr))
99 |
100 | return grp, AimLoc
--------------------------------------------------------------------------------
/Plugcmds/ConvertControl/FaceControlBuilderUI.py:
--------------------------------------------------------------------------------
1 | import os, inspect
2 | from PyQt4 import QtGui, uic
3 | import ConvertControl
4 | import maya.cmds as mc
5 | reload(ConvertControl)
6 | #-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
7 |
8 | def getScriptPath():
9 | PyFile = inspect.getfile(inspect.currentframe())
10 | return os.path.dirname(PyFile)
11 |
12 | WindowClass, BaseClass = uic.loadUiType(os.path.join(getScriptPath(), 'FaceControlBuilderUI.ui'))
13 | class FaceControlBuilderUI(WindowClass, BaseClass):
14 | def __init__(self, parent=None, positionPoint=None):
15 | wnd = parent.findChild(QtGui.QMainWindow, 'FaceControlBuilder')
16 | if wnd:
17 | wnd.show()
18 | wnd.showNormal()
19 | wnd.activateWindow()
20 | return
21 |
22 | super(FaceControlBuilderUI, self).__init__(parent)
23 | self.setupUi(self)
24 | self.show()
25 | #-----------------------------------------------------------------------------------
26 |
27 | self.chara = ''
28 |
29 | #-----------------------------------------------------------------------------------
30 | for child in parent.children():
31 | if not hasattr(child, 'isWindow'):
32 | continue
33 |
34 | if not child.isWindow():
35 | continue
36 |
37 | if child.windowTitle() == 'Face Rig Builder':
38 | self.C_characterDisplayLabel.setText(child.frbCharacterAssetListWidget.currentItem().text())
39 | self.on_actionCurrentCharacterChanged_triggered(True)
40 |
41 | child.frbCharacterAssetListWidget.currentTextChanged.connect(self.C_characterDisplayLabel.setText)
42 | child.frbCharacterAssetListWidget.currentTextChanged.connect(self.on_actionCurrentCharacterChanged_triggered)
43 | break
44 |
45 |
46 |
47 | def on_actionCurrentCharacterChanged_triggered(self, args=None):
48 | if args == None:return
49 | self.chara = str(self.C_characterDisplayLabel.text())
50 | self._refreshVersion()
51 |
52 |
53 | def _refreshVersion(self):
54 | Versions = ConvertControl.getTempLocatorVersions(self.chara)
55 |
56 | self.C_TempLocatorComboBox.clear()
57 | self.C_TempLocatorComboBox.addItems(Versions)
58 | self.C_TempLocatorComboBox.setCurrentIndex(self.C_TempLocatorComboBox.count() - 1)
59 |
60 |
61 | def on_actionVersionChanged_triggered(self, args=None):
62 | if args == None:return
63 | version = str(self.C_TempLocatorComboBox.currentText())
64 | if version == '':
65 | self.C_TempLocatorLineEdit.clear()
66 | else:
67 | self.C_TempLocatorLineEdit.setText(ConvertControl.getVersiondTempLocatorFile(self.chara, version))
68 |
69 |
70 |
71 | def on_actionImportTempLocators_triggered(self, args=None):
72 | if args == None:return
73 | ConvertControl.importLocators(str(self.C_TempLocatorLineEdit.text()))
74 |
75 |
76 | def on_actionPublishTempLocators_triggered(self, args=None):
77 | if args == None:return
78 | ConvertControl.publishTempLocators(self.chara)
79 | self._refreshVersion()
80 |
81 |
82 | def on_actionCreateTempLocators_triggered(self, args=None):
83 | if args == None:return
84 | ConvertControl.makeTempLocators()
85 |
86 |
87 | def on_actionMirrorLocatorsLR_triggered(self, args=None):
88 | if args == None:return
89 | ConvertControl.mirrorTempLocators('L_', 'R_', 'x')
90 |
91 |
92 | def on_actionMirrorLocatorsRL_triggered(self, args=None):
93 | if args == None:return
94 | ConvertControl.mirrorTempLocators('R_', 'L_', 'x')
95 |
96 |
97 |
98 | def on_actionBuildFaceControl_triggered(self, args=None):
99 | if args == None:return
100 | version = str(self.C_TempLocatorComboBox.currentText())
101 | ConvertControl.buildControlOnFace(self.chara, version)
102 |
103 |
104 | def on_C_publishDataButton_clicked(self, args=None):
105 | if args==None:return
106 | filePath = mc.fileDialog2(fm=0, ff='JSON Files (*.json)')[0]
107 | ConvertControl.exportControlData(filePath)
108 |
109 | def on_C_importDataButton_clicked(self, args=None):
110 | if args==None:return
111 | filePath = mc.fileDialog2(fm=1, ff='JSON Files (*.json)')[0]
112 | if not os.path.isfile(filePath):return
113 | ConvertControl.importControlData(filePath)
--------------------------------------------------------------------------------
/Plugcmds/buildTargents.py:
--------------------------------------------------------------------------------
1 | #=================================
2 | # author: changlong.zang
3 | # date: 2014-05-05
4 | #=================================
5 | import os, re
6 | import maya.cmds as mc
7 | from FoleyUtils import uiTool, scriptTool
8 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
9 |
10 | WindowClass, BaseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'buildTargents.ui'))
11 | class BuildTargents(WindowClass, BaseClass):
12 | def __init__(self, parent=None):
13 | if uiTool.windowExists(parent, 'buildTargentsWindow'):
14 | return
15 |
16 | super(BuildTargents, self).__init__(parent)
17 | self.setupUi(self)
18 | self.show()
19 |
20 |
21 | def on_actionLoad_Object_triggered(self, args=None):
22 | if args==None:return
23 | selOBJ = mc.ls(sl=True)
24 | if selOBJ == []:return
25 |
26 | self.LET_Geometry.setText(selOBJ[0])
27 |
28 | blendShapes = mc.ls(mc.listHistory(selOBJ[0]), type='blendShape')
29 | if blendShapes == []:
30 | self.LET_BlendShape.setText('')
31 | return
32 | self.LET_BlendShape.setText(blendShapes[0])
33 |
34 |
35 |
36 | def on_actionClear_triggered(self, args=None):
37 | if args==None:return
38 | self.LET_Geometry.setText('')
39 | self.LET_BlendShape.setText('')
40 |
41 |
42 |
43 | def on_btn_builde_clicked(self, args=None):
44 | if args==None:return
45 | geometry = str(self.LET_Geometry.text())
46 | blendShape = str(self.LET_BlendShape.text())
47 | if not mc.objExists(geometry):return
48 | if not mc.objExists(blendShape):return
49 |
50 | #buildTargents(geometry, blendShape)
51 | targentList = mc.aliasAttr(blendShape, q=True)
52 | targentDict = {}
53 | for i in range(len(targentList)):
54 | if i % 2 != 0:continue
55 | targentDict[targentList[i]] = re.search('\d+', targentList[i+1]).group()
56 |
57 |
58 | #===========================================================
59 | self.progressBar.setMinimum(0)
60 | self.progressBar.setMaximum(len(targentDict))
61 | self.progressLabel.setText('0 / %d'%len(targentDict))
62 | mc.setAttr('%s.en'%blendShape, 0)
63 | #===========================================================
64 | #- builde
65 | v = 0
66 | for name, index in targentDict.iteritems():
67 | targent = mc.duplicate(geometry, n=name)[0]
68 | buildTargent(blendShape, targent, index)
69 |
70 | targentShape = mc.listRelatives(targent, s=True, path=True)
71 | mc.connectAttr('%s.worldMesh[0]'%targentShape[0], '%s.it[0].itg[%s].iti[6000].igt'%(blendShape, index), f=True)
72 |
73 | #--------------------------------------------------------------
74 | v += 1
75 | self.progressBar.setValue(v)
76 | self.progressLabel.setText('%d / %d'%(v, len(targentDict)))
77 | self.progressName.setText(targent)
78 | #--------------------------------------------------------------
79 |
80 | #- move
81 | targents = targentList[::2]
82 | targents.sort()
83 | W = mc.getAttr('%s.bbmx'%geometry)[0][0] - mc.getAttr('%s.bbmn'%geometry)[0][0]
84 | H = mc.getAttr('%s.bbmx'%geometry)[0][1] - mc.getAttr('%s.bbmn'%geometry)[0][1]
85 | for i, targent in enumerate(targents):
86 | for attr in ('tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz'):
87 | mc.setAttr('%s.%s'%(targent, attr), l=False, k=True, cb=True)
88 |
89 | mc.move(W*(i % 15), H*(i // 15 + 1), 0, targent, r=True)
90 |
91 | #================================================
92 | self.progressBar.setMinimum(0)
93 | self.progressBar.setMaximum(1)
94 | self.progressLabel.setText('0 / 0')
95 | self.progressName.setText('{$targent}')
96 | mc.setAttr('%s.en'%blendShape, 1)
97 | #================================================
98 |
99 |
100 |
101 | def buildTargent(blendShape, targentname, weightID):
102 | postions = mc.getAttr('%s.it[0].itg[%s].iti[6000].ipt'%(blendShape, weightID))
103 | if postions == None :return
104 | points = mc.ls(['%s.%s'%(targentname, pnt) for pnt in mc.getAttr('%s.it[0].itg[%s].iti[6000].ict'%(blendShape, weightID))], fl=True)
105 |
106 | for pnt, posi in zip(points, postions):
107 | mc.move(posi[0], posi[1], posi[2], pnt, r=True)
--------------------------------------------------------------------------------
/Plugcmds/blendShapeWeights.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | blendShapeWeightsTool
4 |
5 |
6 |
7 | 0
8 | 0
9 | 344
10 | 171
11 |
12 |
13 |
14 | BlendShape Weights Tool
15 |
16 |
17 |
18 | -
19 |
20 |
21 | QFrame::Panel
22 |
23 |
24 | QFrame::Raised
25 |
26 |
27 | 2
28 |
29 |
30 |
-
31 |
32 |
33 |
34 | 12
35 | 75
36 | true
37 |
38 |
39 |
40 | BlendShape Weights Tool
41 |
42 |
43 | Qt::AlignCenter
44 |
45 |
46 |
47 | -
48 |
49 |
50 |
51 | 10
52 | 75
53 | true
54 |
55 |
56 |
57 | Mirror
58 |
59 |
60 |
61 | -
62 |
63 |
64 | 3
65 |
66 |
-
67 |
68 |
69 |
70 | 0
71 | 25
72 |
73 |
74 |
75 | Envelope
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 | 0
84 | 25
85 |
86 |
87 |
88 | Targets
89 |
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 | 10
99 | 75
100 | true
101 |
102 |
103 |
104 | Invert
105 |
106 |
107 |
108 | -
109 |
110 |
111 | 3
112 |
113 |
-
114 |
115 |
116 |
117 | 0
118 | 25
119 |
120 |
121 |
122 | Envelope
123 |
124 |
125 |
126 | -
127 |
128 |
129 |
130 | 0
131 | 25
132 |
133 |
134 |
135 | Targets
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/Plugcmds/addGroups/addGroups.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | addGroupWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 253
10 | 387
11 |
12 |
13 |
14 | Add Groups
15 |
16 |
17 |
18 |
19 | 3
20 |
21 | -
22 |
23 |
-
24 |
25 |
26 | Search:
27 |
28 |
29 |
30 | -
31 |
32 |
33 |
34 | 10
35 |
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 |
47 |
48 | 0
49 |
50 |
51 | 0
52 |
53 |
-
54 |
55 |
56 | QFrame::NoFrame
57 |
58 |
59 | true
60 |
61 |
62 |
63 |
64 | 0
65 | 0
66 | 233
67 | 282
68 |
69 |
70 |
71 |
-
72 |
73 |
74 |
75 | 25
76 | 0
77 |
78 |
79 |
80 |
81 | 10
82 |
83 |
84 |
85 | cth
86 |
87 |
88 |
89 | -
90 |
91 |
92 | Qt::Vertical
93 |
94 |
95 |
96 | 20
97 | 224
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | -
110 |
111 |
-
112 |
113 |
114 |
115 | 0
116 | 25
117 |
118 |
119 |
120 | +
121 |
122 |
123 |
124 | -
125 |
126 |
127 |
128 | 0
129 | 25
130 |
131 |
132 |
133 | -
134 |
135 |
136 |
137 |
138 |
139 | -
140 |
141 |
142 |
143 | 0
144 | 25
145 |
146 |
147 |
148 | Add
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
--------------------------------------------------------------------------------
/Plugcmds/transSkinWeightsToCluster/transWeights.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Mon, 22 Sep 2014 10:35:13
5 | #========================================
6 | import os.path
7 | import maya.cmds as mc
8 | import maya.mel as mel
9 | from FoleyUtils import scriptTool, uiTool
10 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
11 |
12 | bodywndClass, bodybaseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'transWeights.ui'))
13 | class transWeightsUI(bodywndClass, bodybaseClass):
14 | def __init__(self, parent=None):
15 | if uiTool.windowExists(parent, 'transSkeletonToClusters'):
16 | return
17 |
18 | super(transWeightsUI, self).__init__(parent)
19 | self.setupUi(self)
20 | self.show()
21 |
22 | def on_btn_LoadGeometry_clicked(self, clicked=None):
23 | if clicked == None:return
24 | sel = mc.ls(sl=True)
25 | if len(sel) < 1:
26 | return
27 |
28 | self.LET_Geometry.setText(sel[0])
29 |
30 |
31 | def on_btn_LoadSkeleton_clicked(self, clicked=None):
32 | if clicked == None:return
33 | sel = mc.ls(sl=True, type='joint')
34 | if len(sel) > 0:
35 | self.LET_Skeleton.setText(', '.join(sel))
36 | else:
37 | geometry = str(self.LET_Geometry.text())
38 | if not mc.objExists(geometry):
39 | return
40 | skinNode = mel.eval('findRelatedSkinCluster ' + geometry)
41 | if not mc.objExists(skinNode):
42 | self.LET_Skeleton.setText('')
43 | return
44 | bindJoints = mc.skinCluster(skinNode, q=True, inf=True)
45 | self.LET_Skeleton.setText(', '.join(bindJoints))
46 |
47 |
48 | def on_btn_Start_clicked(self, clicked=None):
49 | if clicked == None:return
50 | geometry = str(self.LET_Geometry.text())
51 | joints = [jnt.strip() for jnt in str(self.LET_Skeleton.text()).split(',')]
52 | joints = [jnt for jnt in joints if mc.objExists(jnt)]
53 |
54 |
55 | self.progressBar_A.setMaximum(len(joints))
56 | self.progressLabel_A.setText('0/%d'%len(joints))
57 |
58 | for i, jnt in enumerate(joints):
59 | #- create cluster
60 | cluster = mc.cluster(geometry, rel=True)
61 |
62 | #- copy weights
63 | res = transSkinWeightsToCluster(geometry, geometry, jnt, cluster[0], self.progressBar_B, self.progressLabel_B)
64 |
65 | #if res:
66 | ##- weight Node
67 | #mc.cluster(cluster[0], e=True, wn=(jnt, jnt))
68 |
69 | ##- delete handle
70 | #mc.delete(cluster[1])
71 |
72 | #- progerss
73 | self.progressBar_A.setValue(i+1)
74 | self.progressLabel_A.setText('%d/%d'%(i+1, len(joints)))
75 |
76 | self.progressBar_A.setValue(0)
77 | self.progressBar_A.setMaximum(1)
78 | self.progressLabel_A.setText('0/0')
79 |
80 |
81 |
82 | def transSkinWeightsToCluster(skinGeometry, clusterGeometry, joint, cluster, progressBar=None, progressLabel=None):
83 | #- get the cluster Node Name..
84 | if mc.nodeType(cluster) == 'transform':
85 | cluster = mc.listConnections(cluster, t='cluster')[0]
86 | else:
87 | pass
88 |
89 | #- get SkinNode Name
90 | skinNode = mel.eval('findRelatedSkinCluster ' + skinGeometry)
91 |
92 | #- set Value
93 | vtxCount = mc.polyEvaluate(skinGeometry, v=True)
94 | try:
95 | jointIndex = mc.skinCluster(skinNode, q=True, inf=True).index(joint)
96 | except ValueError:
97 | mc.delete(cluster)
98 | return False
99 |
100 | #- progress
101 | if progressBar != None:
102 | progressBar.setMaximum(vtxCount)
103 | if progressLabel != None:
104 | progressLabel.setText('0/%d'%vtxCount)
105 |
106 | weights = list()
107 | for i in range(vtxCount):
108 | weights.append(mc.skinPercent(skinNode, '%s.vtx[%s]'%(skinGeometry, i), q=True, v=True)[jointIndex])
109 | #- progress
110 | if progressBar != None:
111 | progressBar.setValue(i)
112 | if progressLabel != None:
113 | progressLabel.setText('%d/%d'%(i, vtxCount))
114 |
115 | mc.setAttr('%s.wl[0].w[0:%d]'%(cluster, vtxCount-1), *weights)
116 |
117 | #- progress
118 | if progressBar != None:
119 | progressBar.setValue(0)
120 | progressBar.setMaximum(1)
121 | if progressLabel != None:
122 | progressLabel.setText('0/0')
123 |
124 | return True
--------------------------------------------------------------------------------
/Plugcmds/FixAnim.py:
--------------------------------------------------------------------------------
1 | import os, inspect, re, json
2 | from PyQt4 import QtCore, uic
3 | import maya.cmds as mc
4 | from FoleyUtils import scriptTool, uiTool
5 |
6 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
7 |
8 | UIfile = os.path.join(scriptTool.getScriptPath(), 'FixAnim.ui')
9 | UIClass, BaseClass = uic.loadUiType(UIfile)
10 |
11 | class FixAnim(UIClass, BaseClass):
12 | def __init__(self, parent=None):
13 | if uiTool.windowExists(parent, 'FixAnimationWindow'):
14 | return
15 |
16 | super(FixAnim, self).__init__(parent)
17 | self.setupUi(self)
18 | self.show()
19 | #----------------------
20 | self.referenceFiles = {}
21 | self.sourceFiles = []
22 |
23 | def on_actionRefreshScene_triggered(self, args=None):
24 | if args == None:return
25 | self.referenceFiles.clear()
26 | self.ReferenceFilescomboBox.clear()
27 | referenceFiles = mc.file(q=True, r=True)
28 | for rFile in referenceFiles:
29 | baseBame = os.path.basename(rFile)
30 | filePath = os.path.dirname(rFile)
31 | self.referenceFiles[baseBame] = filePath
32 | self.ReferenceFilescomboBox.addItem(baseBame)
33 |
34 |
35 |
36 | def on_actionRefreshSourceFiles_triggered(self, args=None):
37 | if args == None:return
38 | self.ReferenceFileSourcecomboBox.clear()
39 | currentFile = str(self.ReferenceFilescomboBox.currentText())
40 | if len(currentFile) == 0:return
41 | self.sourceFiles = os.listdir(self.referenceFiles[currentFile])
42 | for sFile in self.sourceFiles:
43 | if not re.search('.m[ab]$', sFile):continue
44 | self.ReferenceFileSourcecomboBox.addItem(sFile)
45 |
46 |
47 |
48 | def on_actionLoadControls_triggered(self, args=None):
49 | if args == None:return
50 | SelectControl = mc.ls(sl=True)
51 | self.ControlsLineEdit.setText(' '.join(SelectControl))
52 |
53 |
54 |
55 |
56 | def on_actionSetJsonFilePath_triggered(self, args=None):
57 | if args == None:return
58 | filePath = mc.fileDialog2(fileFilter=("JSON Files (*.json)"))
59 | if not filePath:return
60 | self.FilePathLineEdit.setText(filePath[0])
61 |
62 |
63 |
64 | def on_actionRefreshData_triggered(self, args=None):
65 | if args == None:return
66 |
67 | OldReferencePath = str(self.ReferenceFilescomboBox.currentText())
68 | NewReferencePath = str(self.ReferenceFileSourcecomboBox.currentText())
69 | referencePath = self.referenceFiles[OldReferencePath]
70 |
71 |
72 | if not os.path.isfile(os.path.join(referencePath, NewReferencePath)):return
73 | if OldReferencePath == NewReferencePath:return
74 |
75 |
76 | ControlText = str(self.ControlsLineEdit.text())
77 | Controls = re.findall('\S+', ControlText)
78 | if len(Controls) == 0:return
79 |
80 |
81 | JsonFilepath = str(self.FilePathLineEdit.text())
82 | if len(JsonFilepath) == 0:return
83 |
84 |
85 | #-> get Data
86 | data = {}
87 | for ctr in Controls:
88 | frames = mc.keyframe(ctr, q=True)
89 | if not frames:continue
90 | frames = {}.fromkeys(frames, None).keys()
91 |
92 | for fm in frames:
93 | mc.currentTime(fm)
94 | position = mc.xform(ctr, q=True, ws=True, t=True)
95 | rotation = mc.xform(ctr, q=True, ws=True, ro=True)
96 | data.setdefault(ctr, {})[fm] = (position, rotation)
97 |
98 | #-> save Data
99 | f = open(JsonFilepath, 'w')
100 | json.dump(data, f, indent=2)
101 | f.close()
102 |
103 | #-> change reference characters
104 | referenceNode = mc.file(os.path.join(referencePath, OldReferencePath), q=True, rfn=True)
105 | mc.file(os.path.join(referencePath, NewReferencePath), lr=referenceNode)
106 |
107 | #-> read Data
108 | f = open(JsonFilepath, 'r')
109 | data = json.load(f)
110 | f.close()
111 |
112 | #-> set Data
113 | for ctr, values in data.iteritems():
114 | for fm, lst in values.iteritems():
115 | mc.currentTime(fm)
116 | mc.xform(ctr, ws=True, t=lst[0])
117 | mc.xform(ctr, ws=True, ro=lst[1])
118 |
119 | mc.setKeyframe('%s.tx'%ctr)
120 | mc.setKeyframe('%s.ty'%ctr)
121 | mc.setKeyframe('%s.tz'%ctr)
122 | mc.setKeyframe('%s.rx'%ctr)
123 | mc.setKeyframe('%s.ry'%ctr)
124 | mc.setKeyframe('%s.rz'%ctr)
--------------------------------------------------------------------------------
/Plugcmds/addTwistJoints/warningDialog.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dialog
4 |
5 |
6 |
7 | 0
8 | 0
9 | 500
10 | 140
11 |
12 |
13 |
14 | Warning
15 |
16 |
17 | -
18 |
19 |
20 |
21 | 0
22 | 40
23 |
24 |
25 |
26 |
27 | 16777215
28 | 40
29 |
30 |
31 |
32 | image:url(:/icon/Warning.png);
33 |
34 |
35 |
36 |
37 |
38 |
39 | -
40 |
41 |
42 |
43 | 10
44 | 50
45 | false
46 |
47 |
48 |
49 | ?
50 |
51 |
52 | Qt::AlignCenter
53 |
54 |
55 |
56 | -
57 |
58 |
-
59 |
60 |
61 | Qt::Horizontal
62 |
63 |
64 |
65 | 40
66 | 20
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 |
75 | 75
76 | 26
77 |
78 |
79 |
80 |
81 | 9
82 | 75
83 | true
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | :/icon/success.png:/icon/success.png
92 |
93 |
94 |
95 | 18
96 | 18
97 |
98 |
99 |
100 |
101 | -
102 |
103 |
104 |
105 | 75
106 | 26
107 |
108 |
109 |
110 |
111 | 9
112 | 75
113 | true
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | :/icon/delete.png:/icon/delete.png
122 |
123 |
124 |
125 | 13
126 | 13
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | pushButton
141 | clicked()
142 | Dialog
143 | accept()
144 |
145 |
146 | 371
147 | 135
148 |
149 |
150 | 249
151 | 84
152 |
153 |
154 |
155 |
156 | pushButton_2
157 | clicked()
158 | Dialog
159 | reject()
160 |
161 |
162 | 452
163 | 135
164 |
165 |
166 | 249
167 | 84
168 |
169 |
170 |
171 |
172 |
173 |
--------------------------------------------------------------------------------
/Plugcmds/mirrorCtlShp.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | mirrorControlShapeUI
4 |
5 |
6 |
7 | 0
8 | 0
9 | 294
10 | 155
11 |
12 |
13 |
14 | Mirror Control Shape
15 |
16 |
17 | QRadioButton:checked{
18 |
19 | color: rgb(170, 255, 127);
20 | }
21 |
22 |
23 |
24 |
25 | 3
26 |
27 | -
28 |
29 |
30 |
31 | 0
32 | 25
33 |
34 |
35 |
36 |
37 | 10
38 | 50
39 | false
40 |
41 |
42 |
43 | ctl
44 |
45 |
46 |
47 | -
48 |
49 |
50 |
51 |
52 |
53 |
-
54 |
55 |
56 |
57 | 9
58 |
59 |
60 |
61 | Left to Right
62 |
63 |
64 | true
65 |
66 |
67 |
68 | -
69 |
70 |
71 |
72 | 9
73 |
74 |
75 |
76 | Qt::RightToLeft
77 |
78 |
79 | Right to Left
80 |
81 |
82 |
83 |
84 |
85 |
86 | -
87 |
88 |
89 |
-
90 |
91 |
92 | X
93 |
94 |
95 | true
96 |
97 |
98 |
99 | -
100 |
101 |
102 | Qt::Horizontal
103 |
104 |
105 |
106 | 40
107 | 20
108 |
109 |
110 |
111 |
112 | -
113 |
114 |
115 | Y
116 |
117 |
118 |
119 | -
120 |
121 |
122 | Qt::Horizontal
123 |
124 |
125 |
126 | 40
127 | 20
128 |
129 |
130 |
131 |
132 | -
133 |
134 |
135 | Z
136 |
137 |
138 |
139 |
140 |
141 |
142 | -
143 |
144 |
145 |
146 | 0
147 | 25
148 |
149 |
150 |
151 |
152 | 10
153 |
154 |
155 |
156 | Mirror
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/Plugcmds/ReplaceUV/ReplaceUV.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Tue, 22 Jul 2014 17:41:44
5 | #=============================================
6 | import os, re, RemoveUVWasteNode
7 | import maya.cmds as mc
8 | from PyQt4 import QtCore, QtGui
9 | from FoleyUtils import scriptTool, uiTool, publishTool, mathTool
10 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
11 | ASSET_PATH = 'D:/assets'
12 | ASSET_FOLDER = ('character', 'prop', 'Setpiece', 'set')
13 |
14 |
15 | class ListModel(QtCore.QAbstractListModel):
16 | def __init__(self, Listdata=[], parent=None):
17 | super(ListModel, self).__init__(parent)
18 | self.__modelData = Listdata[:]
19 |
20 | def rowCount(self, index=QtCore.QModelIndex()):
21 | return len(self.__modelData)
22 |
23 |
24 | def data(self, index, role):
25 | if role == QtCore.Qt.DisplayRole:
26 | return self.__modelData[index.row()]
27 |
28 |
29 | def clear(self):
30 | self.beginRemoveRows(QtCore.QModelIndex(), 0, self.rowCount())
31 | del self.__modelData[:]
32 | self.endRemoveRows()
33 |
34 | def change(self, L=[]):
35 | self.beginInsertRows(QtCore.QModelIndex(), 0, self.rowCount())
36 | self.__modelData = L[:]
37 | self.endInsertRows()
38 |
39 |
40 |
41 |
42 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'replaceUV.ui'))
43 | class ReplaceUV(windowClass, baseClass):
44 | def __init__(self, parent=None):
45 | if uiTool.windowExists(parent, 'replaceUVwindow'):return
46 |
47 | super(ReplaceUV, self).__init__(parent)
48 | self.setupUi(self)
49 | #----------------
50 | self.__listModel = ListModel()
51 | self.listView.setModel(self.__listModel)
52 | #----------------
53 | self.show()
54 |
55 |
56 | def on_btn_search_clicked(self, clicked=None):
57 | if clicked == None:return
58 | assetName = str(self.let_input.text())
59 | if assetName == '':
60 | return
61 |
62 | self.asset_data = []
63 | model_use_list = []
64 | for folder in ASSET_FOLDER:
65 | for child in os.listdir(os.path.join(ASSET_PATH, folder)):
66 | if not re.match(assetName, child, re.I):
67 | continue
68 |
69 | tup = (folder, child, 'Model', 'publish', 'maya')
70 | f = publishTool.getLastFile(os.path.join(ASSET_PATH, *tup))
71 |
72 | if not os.path.isfile(f):
73 | continue
74 |
75 | model_use_list.append('( %s ) - %s'%(folder, os.path.basename(f)))
76 | self.asset_data.append(f)
77 |
78 | self.__listModel.change(model_use_list)
79 |
80 |
81 |
82 |
83 | def on_btn_replace_clicked(self, clicked=None):
84 | if clicked == None:return
85 |
86 |
87 | polyGeometry = mc.ls(type='mesh')
88 | if not polyGeometry:
89 | print '# Error # No polyGon geometrys...',
90 | return
91 | polyGeometry = (mc.listRelatives(polyGeometry, p=True))
92 | polyGeometry = dict.fromkeys(polyGeometry).keys()
93 |
94 |
95 | selectIndexes = self.listView.selectedIndexes()
96 | if not selectIndexes:
97 | print '# Error # - You must select a model file...',
98 | return
99 | index = selectIndexes[0].row()
100 | modelPath = self.asset_data[index]
101 |
102 |
103 |
104 | if not uiTool.warning(message='Model\'s UV will be replaced, and it can not to undo !!!\nContinue ? ?'):
105 | return
106 |
107 | #- refrence
108 | f = mc.file(modelPath, r=True, namespace='UV')
109 |
110 | self.progressBar.setMaximum(len(polyGeometry))
111 | for i, geo in enumerate(polyGeometry):
112 | self.progressBar.setValue(i)
113 | self.btn_replace.setText('%d%%'%mathTool.setRange(0, len(polyGeometry), 0, 100, i))
114 |
115 | realName = re.search('\w+$', geo).group()
116 | UVgeo = 'UV:%s'%realName
117 | if not mc.objExists(UVgeo):
118 | print '# Warning # There are no model in new file for %s...'%geo
119 | continue
120 | #-
121 | mc.transferAttributes(UVgeo, geo, pos=0, nml=0, uvs=2, col=0, spa=5, sus="map1", tus="map1", sm=0, fuv=0, clb=1)
122 | #-
123 | print '# Result # Copyed UV %s -> %s'%(UVgeo, geo)
124 |
125 | #- delete history
126 | RemoveUVWasteNode.delUVTransferAttributesNode(geo)
127 |
128 | self.progressBar.setMaximum(1)
129 | self.progressBar.setValue(0)
130 | self.btn_replace.setText('Replace')
131 | #- remove refrence
132 | mc.file(f, rr=True)
--------------------------------------------------------------------------------
/Plugcmds/projectTool/ProjectTool.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Sun, 04 Jan 2015 13:39:56
5 | #========================================
6 | import sys, os, functools
7 | from FoleyUtils import scriptTool, uiTool
8 | from PyQt4 import QtCore, QtGui
9 | import maya.cmds as mc
10 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
11 | baseClass, windowClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'ProjectTool_UI.ui'))
12 | class ProjectUI(baseClass, windowClass):
13 | def __init__(self, parent=None):
14 | if uiTool.windowExists(parent, 'ProjectWindow'):
15 | return
16 |
17 | super(ProjectUI, self).__init__(parent)
18 | self.setupUi(self)
19 | self.show()
20 | #-
21 | project_icon = QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'map_pin.png'))
22 | self.btn_getProject.setIcon(project_icon)
23 |
24 | window_icon = QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'windowIcon.png'))
25 | self.setWindowIcon(window_icon)
26 | #-
27 | self.tableModel = TableModel()
28 | self.tableView.setModel(self.tableModel)
29 | #-
30 | self.delegate = Delegate(self)
31 | self.tableView.setItemDelegateForColumn(1, self.delegate)
32 | #-
33 | self.tableView.verticalHeader().setVisible(False)
34 | self.tableView.horizontalHeader().setClickable(False)
35 | self.tableView.horizontalHeader().setMovable(False)
36 | self.tableView.horizontalHeader().setResizeMode(QtGui.QHeaderView.Fixed)
37 | #-
38 | self.resizeEvent(QtGui.QResizeEvent(QtCore.QSize(), QtCore.QSize()))
39 | #-
40 | self.getProjectPath()
41 |
42 |
43 | def resizeEvent(self, event):
44 | self.tableView.setColumnWidth(0, self.tableView.width() * 0.75)
45 | self.tableView.setColumnWidth(1, self.tableView.width() * 0.24)
46 |
47 |
48 | def getProjectPath(self):
49 | #----------------------------
50 | self.project_name = mc.workspace(q=True, sn=True)
51 | self.project_path = mc.workspace(q=True, fn=True)
52 | #-
53 | self.btn_getProject.setText(self.project_name)
54 | #----------------------------
55 | self.tableModel.clear()
56 | for d in os.listdir(self.project_path):
57 | self.tableModel.insertRow([d, ''])
58 | self.tableView.openPersistentEditor(self.tableModel.index(self.tableModel.rowCount() - 1, 1))
59 | self.tableView.setRowHeight(self.tableModel.rowCount() - 1, 25)
60 |
61 |
62 | def on_btn_getProject_clicked(self, args=None):
63 | if args == None:return
64 | self.getProjectPath()
65 |
66 |
67 | def openPath(self, index):
68 | asset = self.tableModel.data(self.tableModel.index(index.row(), 0), QtCore.Qt.DisplayRole)
69 | path = os.path.normpath(os.path.join(self.project_path, asset))
70 | if sys.platform == 'darwin':
71 | os.system('open %s'%path)
72 | else:
73 | os.system('explorer.exe %s'%path)
74 |
75 |
76 | class TableModel(QtCore.QAbstractTableModel):
77 |
78 | HEAD_DATA = 'Asset', 'Button'
79 |
80 | def __init__(self, parent=None):
81 | super(TableModel, self).__init__(parent)
82 | self._data = []
83 |
84 | def columnCount(self, index):
85 | return 2
86 |
87 | def rowCount(self, index=QtCore.QModelIndex()):
88 | return len(self._data)
89 |
90 |
91 | def data(self, index, role):
92 | if role == QtCore.Qt.DisplayRole:
93 | return self._data[index.row()][index.column()]
94 |
95 | if role == QtCore.Qt.FontRole:
96 | return QtGui.QFont('Tahoma', 10)
97 |
98 |
99 | def headerData(self, section, orientation, role):
100 | if role == QtCore.Qt.DisplayRole:
101 | if orientation == QtCore.Qt.Horizontal:
102 | return self.HEAD_DATA[section]
103 |
104 |
105 | def insertRow(self, data, row=0, index=QtCore.QModelIndex()):
106 | row = self.rowCount()
107 | self.beginInsertRows(index, row, row)
108 | self._data.insert(row, data)
109 | self.endInsertRows()
110 |
111 |
112 | def removeRow(self, row, index=QtCore.QModelIndex()):
113 | self.beginRemoveRows(index, row, row)
114 | self._data.pop(row)
115 | self.endRemoveRows()
116 |
117 |
118 | def clear(self):
119 | for i in reversed(range(self.rowCount())):
120 | self.removeRow(i)
121 |
122 |
123 |
124 | class Delegate(QtGui.QItemDelegate):
125 | def __init__(self, parent=None):
126 | super(Delegate, self).__init__(parent)
127 | self.parent = parent
128 | #-
129 | self.folder_icon = QtGui.QIcon(os.path.join(scriptTool.getScriptPath(), 'icons', 'folder.png'))
130 |
131 | def createEditor(self, parent, option, index):
132 | button = QtGui.QPushButton(parent)
133 | button.setIcon(self.folder_icon)
134 | button.clicked.connect(functools.partial(self.parent.openPath, index))
135 | return button
--------------------------------------------------------------------------------
/Plugcmds/TransWeights/TransWeights.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | TransWeightsUI
4 |
5 |
6 |
7 | 0
8 | 0
9 | 317
10 | 100
11 |
12 |
13 |
14 | Trans Weights
15 |
16 |
17 |
18 |
19 | 3
20 |
21 | -
22 |
23 |
24 | 3
25 |
26 |
-
27 |
28 |
29 |
30 | 25
31 | 0
32 |
33 |
34 |
35 |
36 | 10
37 |
38 |
39 |
40 |
41 |
42 |
43 | { $geometry }
44 |
45 |
46 | true
47 |
48 |
49 |
50 | -
51 |
52 |
53 |
54 | 25
55 | 0
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | 13
64 | 13
65 |
66 |
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | 3
75 |
76 |
-
77 |
78 |
79 |
80 | 25
81 | 0
82 |
83 |
84 |
85 |
86 | 10
87 |
88 |
89 |
90 |
91 |
92 |
93 | { $joint }
94 |
95 |
96 | true
97 |
98 |
99 |
100 | -
101 |
102 |
103 |
104 | 25
105 | 0
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | 13
114 | 13
115 |
116 |
117 |
118 |
119 |
120 |
121 | -
122 |
123 |
124 | 3
125 |
126 |
-
127 |
128 |
129 |
130 | 25
131 | 0
132 |
133 |
134 |
135 |
136 | 10
137 |
138 |
139 |
140 | Export
141 |
142 |
143 |
144 | 15
145 | 15
146 |
147 |
148 |
149 |
150 | -
151 |
152 |
153 |
154 | 25
155 | 0
156 |
157 |
158 |
159 |
160 | 10
161 |
162 |
163 |
164 | Import
165 |
166 |
167 |
168 | 15
169 | 15
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
--------------------------------------------------------------------------------
/Plugcmds/ShapeBuilder/cvShapeInverter.py:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2011 Chad Vernon
3 | #
4 |
5 | import maya.OpenMayaMPx as OpenMayaMPx
6 | import maya.OpenMaya as OpenMaya
7 | import math
8 |
9 | class cvShapeInverter(OpenMayaMPx.MPxDeformerNode):
10 | kPluginNodeName = "cvShapeInverter"
11 | kPluginNodeId = OpenMaya.MTypeId(0x00115805)
12 |
13 | aMatrix = OpenMaya.MObject()
14 | aCorrectiveGeo = OpenMaya.MObject()
15 | aDeformedPoints = OpenMaya.MObject()
16 | aActivate = OpenMaya.MObject()
17 |
18 | def __init__(self):
19 | OpenMayaMPx.MPxDeformerNode.__init__(self)
20 | self.__initialized = False
21 | self.__matrices = []
22 | self.__deformedPoints = OpenMaya.MPointArray()
23 | # end __init__
24 |
25 | def deform( self, data, itGeo, localToWorldMatrix, geomIndex):
26 | run = data.inputValue(cvShapeInverter.aActivate).asBool()
27 | if not run:
28 | return 1 #OpenMaya.MStatus.kSuccess
29 |
30 | # Read the matrices
31 | if not self.__initialized:
32 | inputAttribute = OpenMayaMPx.cvar.MPxDeformerNode_input
33 | inputGeom = OpenMayaMPx.cvar.MPxDeformerNode_inputGeom
34 | hInput = data.outputArrayValue(inputAttribute)
35 | hInput.jumpToElement(geomIndex)
36 | oInputGeom = hInput.outputValue().child(inputGeom).asMesh()
37 | fnInputMesh = OpenMaya.MFnMesh(oInputGeom)
38 | numVertices = fnInputMesh.numVertices()
39 |
40 | hMatrix = data.inputArrayValue(cvShapeInverter.aMatrix)
41 | for i in range(numVertices):
42 | self.jumpToElement(hMatrix, i)
43 | self.__matrices.append(hMatrix.inputValue().asMatrix())
44 | # end for
45 |
46 | oDeformedPoints = data.inputValue(cvShapeInverter.aDeformedPoints).data()
47 | fnData = OpenMaya.MFnPointArrayData(oDeformedPoints)
48 | fnData.copyTo(self.__deformedPoints)
49 | self.__initialized = True
50 | # end if
51 |
52 | # Get the corrective mesh
53 | oMesh = data.inputValue(cvShapeInverter.aCorrectiveGeo).asMesh()
54 | fnMesh = OpenMaya.MFnMesh(oMesh)
55 | correctivePoints = OpenMaya.MPointArray()
56 | fnMesh.getPoints(correctivePoints)
57 |
58 | # Perform the inversion calculation
59 | while not itGeo.isDone():
60 | index = itGeo.index()
61 | delta = correctivePoints[index] - self.__deformedPoints[index]
62 |
63 | if (math.fabs(delta.x) < 0.001
64 | and math.fabs(delta.y) < 0.001
65 | and math.fabs(delta.z) < 0.001):
66 | itGeo.next()
67 | continue
68 | # end if
69 |
70 | offset = delta * self.__matrices[index]
71 | pt = itGeo.position() + offset
72 | itGeo.setPosition(pt)
73 | itGeo.next()
74 | # end while
75 |
76 | return 1 #OpenMaya.MStatus.kSuccess
77 | # end deform
78 |
79 |
80 | ## @brief Jumps an array handle to a logical index and uses the builder if necessary.
81 | #
82 | # @param[in/out] hArray MArrayDataHandle to jump.
83 | # @param[in] index Logical index.
84 | #
85 | def jumpToElement(self, hArray, index):
86 | try:
87 | hArray.jumpToElement(index)
88 | except:
89 | builder = hArray.builder()
90 | builder.addElement(index)
91 | hArray.set(builder)
92 | hArray.jumpToElement(index)
93 | # end try
94 | # end jumpToElement
95 |
96 |
97 | def creator():
98 | return OpenMayaMPx.asMPxPtr(cvShapeInverter())
99 | # end creator
100 |
101 |
102 | def initialize():
103 | mAttr = OpenMaya.MFnMatrixAttribute()
104 | tAttr = OpenMaya.MFnTypedAttribute()
105 | nAttr = OpenMaya.MFnNumericAttribute()
106 |
107 | outputGeom = OpenMayaMPx.cvar.MPxDeformerNode_outputGeom
108 |
109 | cvShapeInverter.aActivate = nAttr.create('activate', 'activate',
110 | OpenMaya.MFnNumericData.kBoolean)
111 | cvShapeInverter.addAttribute(cvShapeInverter.aActivate)
112 | cvShapeInverter.attributeAffects(cvShapeInverter.aActivate, outputGeom)
113 |
114 | cvShapeInverter.aCorrectiveGeo = tAttr.create('correctiveMesh', 'cm', OpenMaya.MFnData.kMesh)
115 | cvShapeInverter.addAttribute(cvShapeInverter.aCorrectiveGeo)
116 | cvShapeInverter.attributeAffects(cvShapeInverter.aCorrectiveGeo, outputGeom)
117 |
118 | cvShapeInverter.aDeformedPoints = tAttr.create('deformedPoints', 'dp',
119 | OpenMaya.MFnData.kPointArray)
120 | cvShapeInverter.addAttribute(cvShapeInverter.aDeformedPoints)
121 |
122 | cvShapeInverter.aMatrix = mAttr.create('inversionMatrix', 'im')
123 | mAttr.setArray(True)
124 | mAttr.setUsesArrayDataBuilder(True)
125 | cvShapeInverter.addAttribute(cvShapeInverter.aMatrix)
126 | # end initialize
127 |
128 |
129 | def initializePlugin(mobject):
130 | plugin = OpenMayaMPx.MFnPlugin(mobject)
131 | plugin.registerNode(cvShapeInverter.kPluginNodeName, cvShapeInverter.kPluginNodeId, creator,
132 | initialize, OpenMayaMPx.MPxNode.kDeformerNode)
133 | # end initializePlugin
134 |
135 |
136 | def uninitializePlugin(mobject):
137 | plugin = OpenMayaMPx.MFnPlugin(mobject)
138 | plugin.deregisterNode(cvShapeInverter.kPluginNodeId)
139 | # end uninitializePlugin
140 |
141 |
--------------------------------------------------------------------------------
/Plugcmds/mirrorSDK.py:
--------------------------------------------------------------------------------
1 | import os.path
2 | from PyQt4 import QtGui
3 | import maya.cmds as mc
4 | from FoleyUtils import scriptTool, uiTool
5 |
6 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
7 |
8 |
9 | UIwndClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'mirrorSDK.ui'))
10 | class MirrorSetDrivenKey(UIwndClass, baseClass):
11 | def __init__(self, parent=None):
12 | if uiTool.windowExists(parent, 'mirrorSDKwindow'):
13 | return
14 |
15 | super(MirrorSetDrivenKey, self).__init__(parent)
16 | self.setupUi(self)
17 | self.show()
18 | #-------------
19 | self.sourceAtrLst = []
20 | self.targentAtrLst = []
21 |
22 |
23 | def on_btn_deleteItem_clicked(self, args=None):
24 | if args==None:return
25 |
26 | for item in self.SourceAttributeList.selectedItems():
27 | for x in self.sourceAtrLst:
28 | if x[1] == item.text():
29 | self.sourceAtrLst.remove(x)
30 | break
31 | strings = self.SearchFLD.text()
32 | self.SearchFLD.setText('9999999')
33 | self.SearchFLD.setText(strings)
34 |
35 |
36 | def on_actionInputSearchReplace_triggered(self):
37 | SEARCH = self.SearchFLD.text()
38 | REPLACE = self.ReplaceFLD.text()
39 | OLDDRIVER = self.sourceControlFLD.text()
40 | NEWDRIVER = self.targentControlFLD.text()
41 |
42 | #
43 | self.SourceAttributeList.clear()
44 | sourceAttrs = [x[1] for x in self.sourceAtrLst]
45 | self.SourceAttributeList.addItems(sourceAttrs)
46 | #
47 | self.targentAtrLst = [[x[0].replace(OLDDRIVER, NEWDRIVER), x[1].replace(SEARCH, REPLACE), x[2], x[3]] for x in self.sourceAtrLst]
48 | #
49 | #self.TargentAttributeList.clear()
50 | #SEARCH = self.SearchFLD.text()
51 | #REPLACE = self.ReplaceFLD.text()
52 | #targentAttrs = [x[1] for x in self.targentAtrLst]
53 | #self.TargentAttributeList.addItems(targentAttrs)
54 | targentAttrs = [x[1] for x in self.targentAtrLst]
55 | self.Model = QtGui.QStringListModel()
56 | self.Model.setStringList(targentAttrs)
57 | self.TargentAttributeList.setModel(self.Model)
58 |
59 |
60 | def on_actionLoadSourceControl_triggered(self, clicked=None):
61 | if clicked == None:return
62 | selectOBJ = mc.ls(sl=True)
63 |
64 | if len(selectOBJ) == 0:return
65 | self.sourceControlFLD.setText(selectOBJ[0])
66 |
67 | KeyableAttr = mc.listAttr(selectOBJ[0], k=True)
68 |
69 | del self.sourceAtrLst[:]
70 | del self.targentAtrLst[:]
71 | # loop Attributes..
72 | for Attr in KeyableAttr:
73 | SDKeys = mc.connectionInfo('%s.%s'%(selectOBJ[0], Attr), dfs=True)
74 | # loop driven Attributes..
75 | for key in SDKeys:
76 | if mc.nodeType(key) == 'unitConversion':
77 | keyNode = mc.connectionInfo('%s.output'%key.split('.')[0], dfs=True)[0].split('.')[0]
78 |
79 | elif mc.nodeType(key) not in ('animCurve','animCurveTA', 'animCurveTL', 'animCurveTT','animCurveTU','animCurveUA','animCurveUL','animCurveUT','animCurveUU'):
80 | continue
81 | else:
82 | keyNode = key.split('.')[0]
83 | DriverValues = mc.keyframe(keyNode, q=True, fc=True)
84 | DrivenValues = mc.keyframe(keyNode, q=True, vc=True)
85 | DriverAttribute = mc.connectionInfo('%s.output'%keyNode, dfs=True)[0]
86 |
87 | # if more than one Drivers, from add node get the attribute..
88 | if DriverAttribute.endswith(']'):
89 | DriverAttribute = mc.connectionInfo('%s.output'%(DriverAttribute.split('.')[0]), dfs=True)[0]
90 |
91 | self.sourceAtrLst.append(['%s.%s'%(selectOBJ[0], Attr), DriverAttribute, DriverValues, DrivenValues])
92 |
93 | self.on_actionInputSearchReplace_triggered()
94 |
95 |
96 | def on_actionLoadTargentControl_triggered(self, clicked=None):
97 | if clicked == None:return
98 | selectOBJ = mc.ls(sl=True)
99 |
100 | if len(selectOBJ) == 0:return
101 | self.targentControlFLD.setText(selectOBJ[0])
102 | self.on_actionInputSearchReplace_triggered()
103 |
104 |
105 |
106 | def on_actionMirrorSDK_triggered(self, clicked=None):
107 | if clicked == None:return
108 |
109 | ReverDt = {'X':1, 'Y':1, 'Z':1}
110 |
111 | if self.REVERX.isChecked():ReverDt['X'] = -1
112 | if self.REVERY.isChecked():ReverDt['Y'] = -1
113 | if self.REVERZ.isChecked():ReverDt['Z'] = -1
114 |
115 | for i,DrivenInformations in enumerate(self.targentAtrLst):
116 | DrivenAttr = str(list(self.Model.stringList())[i])
117 | for driverValue, value in zip(DrivenInformations[2], DrivenInformations[3]):
118 | mc.setDrivenKeyframe(DrivenAttr, cd=DrivenInformations[0], dv=driverValue, v=value * ReverDt.get(DrivenInformations[0][-1], 1))
119 | print DrivenInformations[0], DrivenAttr
120 |
121 |
122 |
123 | if __name__ == '__main__':MirrorSetDrivenKey(getMayaWnd())
--------------------------------------------------------------------------------
/Plugcmds/blendShapeWeights.py:
--------------------------------------------------------------------------------
1 | #=============================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Wed, 16 Jul 2014 09:31:17
5 | #=============================================
6 | import os.path
7 | import maya.cmds as mc
8 | import maya.mel as mel
9 | from FoleyUtils import scriptTool, uiTool, mayaTool
10 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
11 | windowClass, baseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'blendShapeWeights.ui'))
12 | class BlendShapeWeightUI(windowClass, baseClass):
13 | def __init__(self, parent=None):
14 | if uiTool.windowExists(parent, 'blendShapeWeightsTool'):return
15 | super(BlendShapeWeightUI, self).__init__(parent)
16 | self.setupUi(self)
17 | self.show()
18 |
19 |
20 | def on_btn_mirrorE_clicked(self, clicked=None):
21 | if clicked == None:return
22 | doMirrorBlendShapeWeights(envelope=True)
23 |
24 |
25 | def on_btn_mirrorT_clicked(self, clicked=None):
26 | if clicked == None:return
27 | doMirrorBlendShapeWeights(envelope=False)
28 |
29 |
30 | def on_btn_inverE_clicked(self, clicked=None):
31 | if clicked == None:return
32 | doInvertBlendShapeWeights(envelope=True)
33 |
34 |
35 | def on_btn_inverT_clicked(self, clicked=None):
36 | if clicked == None:return
37 | doInvertBlendShapeWeights(envelope=False)
38 |
39 |
40 |
41 |
42 |
43 |
44 | def invertBlendShapeWeights(model, blendShape, envelope=True):
45 | #- get vetx
46 | VtxCounts = mc.polyEvaluate(model, v=True)
47 |
48 | # Start the progress bar.
49 | gMainProgressBar = mel.eval('$tmp = $gMainProgressBar')
50 | mc.progressBar(gMainProgressBar, e=True, bp=True, ii=True, st='Applying weights to %s' % model, max=int(VtxCounts))
51 |
52 | for i in range(VtxCounts):
53 | # Increase the progress bar.
54 | if mc.progressBar(gMainProgressBar, q=True, ic=True): break
55 | mc.progressBar(gMainProgressBar, e=True, s=1)
56 |
57 | #- get Value, set Value
58 | if envelope:
59 | value = mc.getAttr('%s.it[0].baseWeights[%d]'%(blendShape, i))
60 | mc.setAttr('%s.it[0].baseWeights[%d]'%(blendShape, i), 1 - value)
61 |
62 | else:
63 | for ID in mayaTool.getActiveTargets(blendShape): #- if attrbute seted..
64 | value = mc.getAttr('%s.it[0].itg[%d].tw[%d]'%(blendShape, ID, i))
65 | mc.setAttr('%s.it[0].itg[%d].tw[%d]'%(blendShape, ID, i), 1 - value)
66 |
67 |
68 | # Stop the progress bar.
69 | mc.progressBar(gMainProgressBar, e=True, ep=True)
70 |
71 |
72 |
73 |
74 |
75 | def mirrorBlendShapeWeights(model, blendShape, envelope=True):
76 | #- get vetx
77 | VtxCounts = mc.polyEvaluate(model, v=True)
78 | #- create Info node
79 | InfoNode = mc.createNode('closestPointOnMesh')
80 | #- connect
81 | mc.connectAttr('%s.outMesh'%mc.listRelatives(model, s=True, path=True)[0], '%s.inMesh'%InfoNode)
82 |
83 | # Start the progress bar.
84 | gMainProgressBar = mel.eval('$tmp = $gMainProgressBar')
85 | mc.progressBar(gMainProgressBar, e=True, bp=True, ii=True, st='Applying weights to %s' % model, max=VtxCounts)
86 |
87 | for i in range(VtxCounts):
88 | # Increase the progress bar.
89 | if mc.progressBar(gMainProgressBar, q=True, ic=True): break
90 | mc.progressBar(gMainProgressBar, e=True, s=1)
91 |
92 | #- get vtx positions
93 | posi = mc.xform('%s.vtx[%d]'%(model, i), q=True, t=True)
94 | if posi[0] < 0:
95 | continue
96 | #- set Info node attributes
97 | mc.setAttr('%s.ip'%InfoNode, posi[0] * -1, *posi[1:])
98 |
99 | #- get mirrord vtx ID
100 | mrID = mc.getAttr('%s.vt'%InfoNode)
101 |
102 | #- get Value, set Value
103 | if envelope:
104 | value = mc.getAttr('%s.it[0].baseWeights[%d]'%(blendShape, i))
105 | mc.setAttr('%s.it[0].baseWeights[%d]'%(blendShape, mrID), value)
106 |
107 | else:
108 | for ID in mayaTool.getActiveTargets(blendShape): #- if attrbute seted..2382
109 | value = mc.getAttr('%s.it[0].itg[%d].tw[%d]'%(blendShape, ID, i))
110 | mc.setAttr('%s.it[0].itg[%d].tw[%d]'%(blendShape, ID, mrID), value)
111 |
112 | # Stop the progress bar.
113 | mc.progressBar(gMainProgressBar, e=True, ep=True)
114 | mc.delete(InfoNode)
115 |
116 |
117 |
118 | @mayaTool.undo_decorator
119 | def doMirrorBlendShapeWeights(envelope=True):
120 | selOBJ = mc.ls(sl=True)
121 | if len(selOBJ) == 0:return
122 |
123 | blendShapes = mayaTool.getHistoryByType(selOBJ[0], 'blendShape')
124 |
125 | if len(blendShapes) == 0:return
126 |
127 | for bs in blendShapes :
128 | mirrorBlendShapeWeights(selOBJ[0], bs, envelope)
129 |
130 |
131 |
132 | @mayaTool.undo_decorator
133 | def doInvertBlendShapeWeights(envelope=True):
134 | selOBJ = mc.ls(sl=True)
135 | if len(selOBJ) == 0:return
136 |
137 | blendShapes = mayaTool.getHistoryByType(selOBJ[0], 'blendShape')
138 |
139 | if len(blendShapes) == 0:return
140 |
141 | for bs in blendShapes :
142 | invertBlendShapeWeights(selOBJ[0], bs, envelope)
--------------------------------------------------------------------------------
/Plugcmds/mirrorBlendShapeWeights.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 245
10 | 97
11 |
12 |
13 |
14 |
15 | 0
16 | 0
17 |
18 |
19 |
20 | Mirror BlendShape Weights
21 |
22 |
23 |
24 |
25 | 3
26 |
27 |
28 | 6
29 |
30 | -
31 |
32 |
-
33 |
34 |
-
35 |
36 |
37 | Mirror across:
38 |
39 |
40 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
41 |
42 |
43 |
44 | -
45 |
46 |
47 | Qt::Horizontal
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 | 0
56 | 0
57 |
58 |
59 |
60 |
61 | 16777215
62 | 16777215
63 |
64 |
65 |
66 | Direction:
67 |
68 |
69 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
70 |
71 |
72 |
73 |
74 |
75 | -
76 |
77 |
78 | Qt::Vertical
79 |
80 |
81 |
82 | -
83 |
84 |
-
85 |
86 |
87 |
-
88 |
89 |
90 | XY
91 |
92 |
93 |
94 | -
95 |
96 |
97 | YZ
98 |
99 |
100 | true
101 |
102 |
103 |
104 | -
105 |
106 |
107 | XZ
108 |
109 |
110 |
111 |
112 |
113 |
114 | -
115 |
116 |
117 | Qt::Horizontal
118 |
119 |
120 |
121 | -
122 |
123 |
124 |
-
125 |
126 |
127 | +X to -X
128 |
129 |
130 | true
131 |
132 |
133 |
134 | -
135 |
136 |
137 | -X to +X
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | -
149 |
150 |
151 | 2
152 |
153 |
-
154 |
155 |
156 | Envelope
157 |
158 |
159 |
160 | -
161 |
162 |
163 | Targets
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
--------------------------------------------------------------------------------
/Plugcmds/blendShapeWeightsTool/blendShapeWeights.py:
--------------------------------------------------------------------------------
1 | #========================================
2 | # author: changlong.zang
3 | # mail: zclongpop@163.com
4 | # date: Thu, 14 Aug 2014 10:30:06
5 | #========================================
6 | import os.path, re
7 | from FoleyUtils import scriptTool, uiTool, mayaTool
8 | from PyQt4 import QtCore
9 | import maya.cmds as mc
10 | #--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
11 | class ListModel(QtCore.QAbstractListModel):
12 | def __init__(self, parent=None):
13 | super(ListModel, self).__init__(parent)
14 | self.__data = []
15 |
16 | def rowCount(self, index):
17 | return len(self.__data)
18 |
19 |
20 | def data(self, index, role):
21 | if role == QtCore.Qt.DisplayRole:
22 | return self.__data[index.row()]
23 |
24 | def changeData(self, L):
25 | self.beginRemoveRows(QtCore.QModelIndex(), 0, len(self.__data))
26 | self.__data = L
27 | self.endRemoveRows()
28 |
29 |
30 | bodywndClass, bodybaseClass = uiTool.loadUi(os.path.join(scriptTool.getScriptPath(), 'blendShapeWeights.ui'))
31 | class BlendShapeWeightsUI(bodywndClass, bodybaseClass):
32 | def __init__(self, parent=None):
33 | if uiTool.windowExists(parent, 'blendShapeWeightsToolUI'):
34 | return
35 |
36 | super(BlendShapeWeightsUI, self).__init__(parent)
37 | self.setupUi(self)
38 | self.show()
39 | #-
40 | self.__skinModel = ListModel()
41 | self.__bspModel = ListModel()
42 | self.VIEW_skin.setModel(self.__skinModel)
43 | self.VIEW_bsp.setModel(self.__bspModel)
44 |
45 |
46 |
47 | def on_actionLoadSkinCluster_triggered(self, args=None):
48 | if args == None:return
49 | selSkin = mc.ls(sl=True, type='skinCluster')
50 | if len(selSkin) < 1:
51 | return
52 | self.LET_skin.setText(selSkin[0])
53 | #-
54 | influcens = mc.skinCluster(selSkin[0], q=True, inf=True)
55 | self.__skinModel.changeData(influcens)
56 |
57 |
58 |
59 |
60 | def on_actionLoadBlendShape_triggered(self, args=None):
61 | if args == None:return
62 | selBsp = mc.ls(sl=True, type='blendShape')
63 | if len(selBsp) < 1:
64 | return
65 | self.LET_bsp.setText(selBsp[0])
66 | #-
67 | attributes = mayaTool.getBlendShapeAttributes(selBsp[0])
68 | self.__bspModel.changeData(attributes)
69 |
70 |
71 |
72 | def on_btn_copyWeights_clicked(self, args=None):
73 | if args==None:return
74 | skinNode = str(self.LET_skin.text())
75 | bspNode = str(self.LET_bsp.text())
76 | influcenIndex = self.VIEW_skin.selectedIndexes()[0].row()
77 | bspAttribute = self.VIEW_bsp.selectedIndexes()[0].row()
78 |
79 | skinGeo = mc.skinCluster(skinNode, q=True, g=True)[0]
80 | if mc.nodeType(skinGeo) != 'mesh':
81 | return
82 |
83 | VtxCounts = mc.polyEvaluate(skinGeo, v=True)
84 | self.progressBar.setMaximum(VtxCounts)
85 | for i in range(VtxCounts):
86 | value = mc.skinPercent(skinNode, '%s.vtx[%d]'%(skinGeo, i), q=True, v=True)
87 | Skin_weight_value = value[influcenIndex]
88 | mc.setAttr('%s.it[0].itg[%d].tw[%d]'%(bspNode, bspAttribute, i), Skin_weight_value)
89 | self.progressBar.setValue(i)
90 | self.progressBar.setValue(0)
91 |
92 |
93 | #-------------------------------------------------------------------------------------------------
94 |
95 | def on_CBX_weightValue_editingFinished(self):
96 | value = self.CBX_weightValue.value()
97 | self.SLD_weightValue.setValue(value * 1000)
98 |
99 |
100 | def on_SLD_weightValue_valueChanged(self, value):
101 | self.CBX_weightValue.setValue(value / 1000.0)
102 |
103 |
104 | def getId(self):
105 | ids = []
106 | for vtx in mc.ls(sl=True, fl=True):
107 | if not re.search('(?<=\[)\d+(?=\])', vtx):
108 | continue
109 | ids.append(int(re.search('(?<=\[)\d+(?=\])', vtx).group()))
110 | return ids
111 |
112 |
113 | def on_btn_addWeights_clicked(self, args=None):
114 | if args==None:return
115 | bspNode = str(self.LET_bsp.text())
116 | bspAttribute = self.VIEW_bsp.selectedIndexes()[0].row()
117 | value = self.CBX_weightValue.value()
118 | for i in self.getId():
119 | ov = mc.getAttr('%s.it[0].itg[%d].tw[%d]'%(bspNode, bspAttribute, i))
120 | mc.setAttr('%s.it[0].itg[%d].tw[%d]'%(bspNode, bspAttribute, i), ov + value)
121 |
122 |
123 | def on_btn_minusWeights_clicked(self, args=None):
124 | if args==None:return
125 | bspNode = str(self.LET_bsp.text())
126 | bspAttribute = self.VIEW_bsp.selectedIndexes()[0].row()
127 | value = self.CBX_weightValue.value()
128 | for i in self.getId():
129 | ov = mc.getAttr('%s.it[0].itg[%d].tw[%d]'%(bspNode, bspAttribute, i))
130 | mc.setAttr('%s.it[0].itg[%d].tw[%d]'%(bspNode, bspAttribute, i), ov - value)
131 |
132 |
133 | def on_btn_floodWeights_clicked(self, args=None):
134 | if args==None:return
135 | bspNode = str(self.LET_bsp.text())
136 | bspAttribute = self.VIEW_bsp.selectedIndexes()[0].row()
137 | value = self.CBX_weightValue.value()
138 | for i in self.getId():
139 | mc.setAttr('%s.it[0].itg[%d].tw[%d]'%(bspNode, bspAttribute, i), value)
--------------------------------------------------------------------------------
/Plugcmds/quickSDKTool.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | quickSDKwindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 300
10 | 428
11 |
12 |
13 |
14 | Quick S.D.K
15 |
16 |
17 | background-color: rgb(68, 68, 68);
18 |
19 |
20 |
21 |
22 |
23 | 10
24 | 10
25 | 281
26 | 371
27 |
28 |
29 |
30 |
31 |
32 |
33 | -
34 |
35 |
36 |
37 | 0
38 | 24
39 |
40 |
41 |
42 |
43 | 0
44 | 24
45 |
46 |
47 |
48 |
49 | 16777215
50 | 24
51 |
52 |
53 |
54 |
55 | 9
56 | 75
57 | true
58 |
59 |
60 |
61 | color: rgb(231, 227, 174);
62 | background-color: rgb(42, 42, 42);
63 |
64 |
65 | true
66 |
67 |
68 |
69 | -
70 |
71 |
72 |
73 | MS Shell Dlg 2
74 | 10
75 | 50
76 | false
77 | true
78 |
79 |
80 |
81 | color: rgb(227, 111, 92);
82 | alternate-background-color: rgb(82, 82, 82);
83 | background-color: rgb(42, 42, 42);
84 |
85 |
86 | false
87 |
88 |
89 | false
90 |
91 |
92 | true
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | 10
102 | 390
103 | 281
104 | 31
105 |
106 |
107 |
108 | -
109 |
110 |
111 |
112 | 0
113 | 28
114 |
115 |
116 |
117 |
118 | 75
119 | true
120 |
121 |
122 |
123 | Load
124 |
125 |
126 |
127 | -
128 |
129 |
130 |
131 | 0
132 | 28
133 |
134 |
135 |
136 |
137 | 75
138 | true
139 |
140 |
141 |
142 | Set Driven Key
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 | LoadAttributesPushButton
152 |
153 |
154 |
155 |
156 | quickSDK
157 |
158 |
159 |
160 |
161 |
162 |
163 | LoadAttributesPushButton
164 | clicked()
165 | actionLoadAttributes
166 | trigger()
167 |
168 |
169 | 79
170 | 404
171 |
172 |
173 | -1
174 | -1
175 |
176 |
177 |
178 |
179 | SDKpushButton
180 | clicked()
181 | actionQuickSDK
182 | trigger()
183 |
184 |
185 | 221
186 | 404
187 |
188 |
189 | -1
190 | -1
191 |
192 |
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/Plugcmds/DynControl/DynControlUI.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | dynControlWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 324
10 | 424
11 |
12 |
13 |
14 | Dyn Control
15 |
16 |
17 |
18 |
19 | 9
20 |
21 | -
22 |
23 |
24 |
25 |
26 |
27 |
28 | 2
29 |
30 |
31 | 3
32 |
33 |
-
34 |
35 |
36 |
37 | 0
38 | 28
39 |
40 |
41 |
42 | Create
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 |
52 |
53 | 2
54 |
55 |
-
56 |
57 |
58 | QFrame::NoFrame
59 |
60 |
61 | true
62 |
63 |
64 |
65 |
66 | 0
67 | 0
68 | 292
69 | 304
70 |
71 |
72 |
73 |
74 | 2
75 |
76 |
-
77 |
78 |
79 |
80 | 0
81 | 0
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | -
97 |
98 |
99 |
100 | 0
101 | 28
102 |
103 |
104 |
105 | Connect
106 |
107 |
108 |
109 | -
110 |
111 |
112 |
113 | 0
114 | 26
115 |
116 |
117 |
118 | Rig Joints
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | createDynControl
130 |
131 |
132 |
133 |
134 | connectHairSystem
135 |
136 |
137 |
138 |
139 | rigJoints
140 |
141 |
142 |
143 |
144 |
145 |
146 | pushButton
147 | clicked()
148 | actionCreateDynControl
149 | trigger()
150 |
151 |
152 | 161
153 | 26
154 |
155 |
156 | -1
157 | -1
158 |
159 |
160 |
161 |
162 | pushButton_2
163 | clicked()
164 | actionConnectHairSystem
165 | trigger()
166 |
167 |
168 | 161
169 | 396
170 |
171 |
172 | -1
173 | -1
174 |
175 |
176 |
177 |
178 | pushButton_3
179 | clicked()
180 | actionRigJoints
181 | trigger()
182 |
183 |
184 | 161
185 | 397
186 |
187 |
188 | -1
189 | -1
190 |
191 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------