├── 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 | --------------------------------------------------------------------------------