Scripts 2018 - Thiago Paulino
During my demoreel final stages of development, a few tools were necessary to achieve the desired goals.
Some of them, like this first one, were attempts to create dynamic neck and trapezius solutions, which ended up being discarded for better solutions, like Maya Muscle, which provides out of the box muscle mirroring, consistent deformations, and robust simulation control.
I've chosen to script in MEL in order to move faster, by observing Maya system output. Understanding Mayas flag system and object oriented approach was crucial, and the knowledge acquired can now be translated to Python.
The first script in this article is demonstrated in second 00:00:45 below:
DYNAMIC RAMP CLUSTER WEIGHT TOOL v0.1
"""CLUSTER DYNAMIC RAMP WEIGHT TOOL v0.1
crated by Thiago Paulino - tpaulino.com - 2018"""
# Pre-declaring variables to avoid illigal re-declarations
string $getSel[];
string $shapeQ[];
string $shapeName;
string $clsName[];
float $curveDeg;
float $curveSpa;
float $cvCount;
string $newExpr2;
string $rampNode;
string $plcd2dTx;
string $cnnctList;
# Get curve information - start
# Get shape curve shape node name
$getSel = `ls -sl`;
$shapeQ = `listRelatives -s $getSel`;
$shapeName = $shapeQ[0];
$clsName = `listConnections -type cluster $shapeName`;
# Get degrees and spans to calculte CVs
$curveDeg = `getAttr ($shapeName + ".degree")`;
$curveSpa = `getAttr ($shapeName + ".spans")`;
# CV's = degrees + spans
$cvCount = $curveDeg + $curveSpa;
# Creates and connects ramp node
$rampNode = `shadingNode -asTexture -name ($getSel[0] + "_" + $clsName[0] + "_ramp") ramp`;
$plcd2dTx = `shadingNode -asUtility place2dTexture`;
connectAttr -f ($plcd2dTx + ".outUV") ($rampNode + ".uvCoord");
connectAttr -f ($plcd2dTx + ".outUvFilterSize") ($rampNode + ".uvFilterSize");
# Creates connection lists for expression printing
for ($y=0; $y<=($cvCount - 1); $y++){
$cnnctList += ($clsName[0] + ".weightList[0].weights[" + $y + "] = $cvValue[" + $y + "];\n");
}
# Stores code in string for expression printing
$newExpr2 = "vector $exprTrigger = " + $rampNode + ".outAlpha; \n\
float $cvValue[]; \n\
// cvCount is dynamic from curve \n\
float $cvCount = " + ($cvCount - 1) + "; \n \n\
for ($y=0; $y<=$cvCount; $y++){ \n\
float $j = $y; \n\
float $pos = ($j/$cvCount); \n\
float $value[] = `colorAtPoint -o A -u 0.5 -v $pos " + $rampNode + "`; \n\
$cvValue[$y] = $value[0]; \n\
} \n \n";
print ($newExpr2 + $cnnctList);
expression -s ($newExpr2 + $cnnctList) -o "" -n ($getSel[0] + "_" + $clsName[0] + "_expr") -ae 0 -uc all ;
# clearing variable to avoid acumulation - Send to the end
$cnnctList = "";
$newExpr2 = "";
select -r $rampNode ;
"""
DEVELOPMENT LIST
- Add conditional for multiple clusters on next version
- Add interface for:
- Curve rebuild CV number
- Deleting native extra 2 CVs
- Apply to all curves in group
- Create controls
- Interpolation method on initialize
"""
--------
DUPLICATE AND RENAME JOINT CHAIN v0.1
"""
DUPLICATE AND RENAME JNT CHAIN
- Select first joint in chain to be duplicated
- Type desired prefix name in first variable
- Run script
"""
string $jointChain[];
string $jntChainSlct[];
string $jntChainCopy2[];
string $jntChainRoot2;
string $prefix;
string $slctSide;
string $sysChoice;
# USER ACTION - Set prefix name
$sysChoice = "ik";
# Start listing
$jntChainSlct = `ls -sl`;
$jntChainCopy2 = `duplicate -rr -rc`;
# Store side prefix - l_ or r_
$slctSide = `substring $jntChainCopy2[0] 1 2`;
# Defines side and assemble new name
if ($slctSide == "l_") {
$prefix = "l_" + $sysChoice + "Sys_";
} else {
$prefix = "r_" + $sysChoice + "Sys_";
}
# Action start
$jntChainRoot2 = $jntChainCopy2[0];
select -r $jntChainCopy2[0];
parent -w;
$jointChain = `listRelatives -ad -type joint $jntChainCopy2`;
appendStringArray ($jntChainCopy2, $jointChain, size($jointChain));
for ($n in $jntChainCopy2) {
string $newName = substituteAllString($n, $slctSide, $prefix);
string $nameCleanUp = substituteAllString($newName, "_jnt1", "_jnt");
select -r $n;
rename $n $nameCleanUp;
}
# DUPLICATEW AND RENAME JNT CHAIN -- END
------
AUTO IK CHAIN v0.1
"""
AUTO IK CHAIN CREATOR v0.1
- Creates IK handle between first and last joint on selected chain
- Creates NURBS circle on second joint of chain - match rotation
- Creates PoleVector Constrain on Circle
"""
string $plcIkChain[];
string $fullChain[];
string $plcIkJnt[];
float $polePos;
int $convertPos;
string $nCircle2[];
string $circleGrp2[];
string $newIk[];
string $pvAimName;
$plcIkJnt = `ls -sl`;
# List chain
$plcIkChain = `listRelatives -ad -type joint $plcIkJnt[0]`;
$polePos = size($plcIkChain) - 1;
$convertPos = $polePos;
# CREATE CIRCLE AND MATCH ---
# Create cricle - Rename - Group - Rename - Match Transforms of second joint
$pvAimName = substituteAllString($plcIkJnt[0], "_jnt", "_pvAim");
$nCircle2 = `circle -n $pvAimName -nr 0 1 0`;
doGroup 0 1 1;
$circleGrp2 = `listRelatives -p $nCircle2`;
select -r $circleGrp2[0];
select -add $plcIkChain[$convertPos];
matchTransform;
select -r $circleGrp2[0];
rename $circleGrp2[0] ($pvAimName + "_grp");
# ---
# Creates IK Handle
select -r $plcIkJnt ;
select -add $plcIkChain[0] ;
$newIk = `ikHandle`;
setAttr ($newIk[0] + ".stickiness") 1;
# Contrain to circle
select -r $nCircle2;
select -add $newIk[0];
PoleVectorConstraint;
# AUTO IK SYSTEM CREATOR -- END
------
IK/FK SYSTEM - PAIR BLEND - CREATE & CONNECT 3 CHAINS v0.1
"""
IK/FK SYS - PAIR BLEND NODES - CREATE AND CONNECT
- Change first joint in hierarchy NAME before runing script
- Creates pair blend nodes
- Connects related joints
- Connects all pair blend nodes weight to single float
"""
string $outputChain;
string $ikChain;
string $fkChain;
string $floatCtrl;
string $outputJnts[];
string $ikJnts[];
string $fkJnts[];
# USER ACTION - Change chain names
$outputChain = "l_humerusOffset_jnt";
$ikChain = "l_ikSys_humerusOffset_jnt";
$fkChain = "l_fkSys_humerusOffset_jnt";
$outputJnts = `listRelatives -ad -type joint $outputTree`;
$ikJnts = `listRelatives -ad -type joint $ikTree`;
$fkJnts = `listRelatives -ad -type joint $fkTree`;
$floatCtrl = `shadingNode -asUtility floatConstant`;
for ($t=0; $t<=(size($outputJnts)-1); $t++) {
string $newPairBlend = `createNode -n ($outputJnts[$t] + "_blnd") "pairBlend"` ;
connectAttr -f ($ikJnts[$t] + ".translate") ($newPairBlend + ".inTranslate1");
connectAttr -f ($ikJnts[$t] + ".rotate") ($newPairBlend + ".inRotate1");
connectAttr -f ($fkJnts[$t] + ".translate") ($newPairBlend + ".inTranslate2");
connectAttr -f ($fkJnts[$t] + ".rotate") ($newPairBlend + ".inRotate2");
connectAttr -f ($newPairBlend + ".outRotate") ($outputJnts[$t] + ".rotate");
connectAttr -f ($newPairBlend + ".outTranslate") ($outputJnts[$t] + ".translate");
connectAttr -f ($floatCtrl + ".outFloat") ($newPairBlend + ".weight");
}
""" IK/FK SYS - PAIR BLEND NODES - END"""
-------
FK SYSTEM - CREATE AND RENAME CONTROLS v0.1
"""
CREATE FK CTRLS FOR EACH JOINT AND NAME IT AS JOINT
- Create cricle on 000
- Rename
- Group
- Rename Grp
- Match grp transforms of joint
"""
string $rootJnt[];
string $jntChain[];
string $jntCtrlName;
$rootJnt = `ls -sl`;
$jntChain = `listRelatives -ad -type joint $rootJnt`;
for ($f=0; $f<=(size($jntChain)-1); $f++) {
$jntCtrlName = substituteAllString($jntChain[$f], "_jnt", "_ctrl");
$crvCtrl = `circle -n $jntCtrlName -nr 1 0 0`;
doGroup 0 1 1;
$crvPrnt = `listRelatives -p $crvCtrl`;
select -r $crvPrnt[0];
select -add $jntChain[$f];
matchTransform;
select -r $crvPrnt[0];
rename $crvPrnt[0] ($jntCtrlName + "_grp");
}
"""
DEVELOPMENT LIST
- Parent contrain ctrls to joints
"""
# CREATE FK CNTRLS -- END
--------
RIGGING UTILITY SCRIPTS V0.1
"""001-"""
""" PARENT JOINT IN SELECTION ORDER"""
string $jntSlct[] = `ls - sl`;
for ($f=0; $f<=(size($jntSlct)-1); $f++) {
if ($f == 0) {
select -r $jntSlct[$f] ;
} else {
select -r $jntSlct[$f] ;
select -add $jntSlct[$f -1] ;
parent ;
}
}
"""002- """
""" COPY PASTE FOLICLE POSITION - MULTI GROUP"""
string $copyGrp[] = `listRelatives -c l_softEye_flc_sys` ;
string $pasteGrp[] = `listRelatives -c r_softEye_flc_sys` ;
float $parU1 ;
float $parV1 ;
float $mirrorParU ;
float $mirrorParV ;
for ($r=0; $r<=(size($copyGrp)-1); $r++) {
string $copyFlc[] = `listRelatives -c $copyGrp[$r]` ;
string $pasteFlc[] = `listRelatives -c $pasteGrp[$r]` ;
for ($t=0; $t<=(size($copyFlc)-1); $t++) {
$parU1 = `getAttr ($copyFlc[$t] + ".parameterU")` ;
$parV1 = `getAttr ($copyFlc[$t] + ".parameterV")` ;
$mirrorParU = $parU1 ;
$mirrorParV = 1 - $parV1 ;
setAttr ($pasteFlc[$t] + ".parameterU") ($mirrorParU) ;
setAttr ($pasteFlc[$t] + ".parameterV") ($mirrorParV) ;
}
}
"""003- """
""" CREATE AND CONNECT PAIR BLEND NODES"""
string $ctrlFlcs[] = `listRelatives -c r_upLid_endRef_ctrl_flc_grp`;
string $inFlcs[] = `listRelatives -c r_bLid_startRef_flc_grp`;
string $outFlcs[] = `listRelatives -c r_bLid_endRef_flc_grp`;
for ($t=0; $t<=(size($ctrlFlcs)-1); $t++) {
string $nodeList = `createNode "pairBlend"` ;
connectAttr -f ($inFlcs[$t] + ".parameterU") ($nodeList + ".inTranslate1.inTranslateX1");
connectAttr -f ($inFlcs[$t] + ".parameterV") ($nodeList + ".inTranslate1.inTranslateY1");
connectAttr -f ($outFlcs[$t] + ".parameterU") ($nodeList + ".inTranslate2.inTranslateX2");
connectAttr -f ($outFlcs[$t] + ".parameterV") ($nodeList + ".inTranslate2.inTranslateY2");
connectAttr -f ($nodeList + ".outTranslateX") ($ctrlFlcs[$t] + ".parameterU");
connectAttr -f ($nodeList + ".outTranslateY") ($ctrlFlcs[$t] + ".parameterV");
connectAttr -f r_eyeBlid_ctrl_float.outFloat ($nodeList + ".weight");
}
"""004- """
"""-- COPY FOLICLE POSITION v1 """
string $copyGrp[];
string $pasteGrp[];
float $parU1;
float $parV1;
# Copy from:
$copyGrp = `listRelatives -c outRef_eyeCtrl_flc_grp` ;
# Paste in:
$pasteGrp = `listRelatives -c bLid_outRef_flc_grp` ;
for ($o=0; $o<=(size($copyGrp)); $o++) {
// Get attr is not array - remember
$parU1 = `getAttr ($copyGrp[$o] + ".parameterU")`;
$parV1 = `getAttr ($copyGrp[$o] + ".parameterV")`;
setAttr ($pasteGrp[$o] + ".parameterU") ($parU1) ;
setAttr ($pasteGrp[$o] + ".parameterV") ($parV1) ;
}
#for ($pastePos in $copyGrp) {
# float $parU[] = `getAttr ($pastePos + ".parameterU")`;
# float $parV[] = `getAttr ($pastePos + ".parameterV")`;
#
# setAttr ($pasteGrp[$v] + ".parameterU") ($parU[0]) ;
# setAttr ($pasteGrp[$v] + ".parameterV") ($parV[0]) ;
#
# $v+= 1 ;
#}
"""005- """
""" JNTS IN SELECTED FOLICLES"""
string $ctrlFlc[] = `ls - sl`;
for ($flcCnnct in $ctrlFlc) {
""" Places circle curves in folicles"""
#string $newCircle[] = `circle`;
#select -r $newCircle;
#select -add $flcCnnct;
#parent;
#setAttr ($newCircle[0] + ".rotateZ") 0;
#setAttr ($newCircle[0] + ".translateX") 0;
#setAttr ($newCircle[0] + ".translateY") 0;
#setAttr ($newCircle[0] + ".translateZ") 0;
#setAttr ($newCircle[0] + ".rotateX") 0;
#setAttr ($newCircle[0] + ".rotateY") 0;
""" Joints in circles in folicles"""
#string $newCircle[] = `circle`;
#select -r $newCircle;
#select -add $flcCnnct;
#parent;
#setAttr ($newCircle[0] + ".rotateZ") 0;
#setAttr ($newCircle[0] + ".translateX") 0;
#setAttr ($newCircle[0] + ".translateY") 0;
#setAttr ($newCircle[0] + ".translateZ") 0;
#setAttr ($newCircle[0] + ".rotateX") 0;
#setAttr ($newCircle[0] + ".rotateY") 0;
#setAttr ($newCircle[0] + ".scaleX") 0.1;
#setAttr ($newCircle[0] + ".scaleY") 0.1;
#setAttr ($newCircle[0] + ".scaleZ") 0.1;
#channelBoxCommand -freezeScale ;
""" Place joints in selected folicles"""
select -r $flcCnnct ;
string $newJnt = `joint` ;
setAttr ($newJnt + ".radius") 0.1 ;
#//setAttr ($flcCnnct + ".parameterU") 1;
#//connectAttr -f floatConstant1.outFloat ($flcCnnct + ".parameterU") ;
}
--------
CURVE MOTION PATH + JOINTS v0.1
"""
Created by Thiago Paulino (tpaulino.com) at VFS 2018 - 3D131
CURVE MOTION PATH + JOINT v0.1
- Creates defined number of motion paths in curve
- Breaks locators connections
- Position locators in equal distances
- Place joint on each
"""
# Stores curve names
string $mPaths[] = `ls -sl`;
float $listSize = `size($mPaths)`;
# USER ACTION - Define number of joints per curve
float $jntQt = 4;
for ($t=0; $t<=$listSize; $t++){
float $jntPos = 0;
for ($x=0; $x<=$jntQt; $x++){
# Create locator
string $targetLoc[] = `spaceLocator -p 0 0 0`;
# Selects locator and motion path curve
select -r $targetLoc ;
select -tgl $mPaths[$t] ;
# Creates motion path constrain
pathAnimation -fractionMode true -follow true -followAxis x -upAxis y -worldUpType "vector" -worldUpVector 0 1 0 -inverseUp false -inverseFront false -bank false -startTimeU `playbackOptions -query -minTime` -endTimeU `playbackOptions -query -maxTime`;
# Deleting animatrion
string $locP[] = `listConnections $targetLoc`;
CBdeleteConnection ($locP[10] + ".u");
# Finding locator position acording to number in the loop
setAttr ($locP[10] + ".uValue") (1 / $jntQt * $x);
# Selects locator and crate joint
select -r $targetLoc ;
joint;
}
}
Python TD
6 个月Great bro
IT advisor, e-Gov, Digital Transition, Senior Project Manager
6 年Great. Thanks for sharing.
Faculty member of UIA/ 3D Generalist Exodo Animation
6 年I admire the way you explain the process and development of this project