appwiki:maya:mel

Differences

This shows you the differences between two versions of the page.


appwiki:maya:mel [2021/08/22 19:59] (current) – created ying
Line 1: Line 1:
 +
 +====== Links ======
 +
 +Mel dev ref resource:
 +  * maya gui structure: install_dir/scripts/startup
 +  * bonus tool mel dir: autodesk_install_dir/bonusTools
 +  * http://caad.arch.ethz.ch/info/maya/manual/Commands/functionalCmdList.html
 +
 +
 +Mel scripting guide:
 +  * 10 to do and not to do: http://xyz2.net/mel/mel.095.htm
 +  * a solid mel outline tutorial: http://www.polyextrude.com/tutorials/MelScripting/index.html
 +
 +some tools to study:
 +  * point tweaker by nurbs: [[http://dissentgraphics.com/tools/zentools/|ZenTool]]
 +  * A list of rigging tools by Supercrumbly: http://www.supercrumbly.com/3d.php
 +  * A list of rigging tools by Zoo: http://www.macaronikazoo.com/
 +
 +====== Access Maya object and Maya object concepts======
 +
 +  * Curve (Nurbs curve)
 +    * Curve structure
 +      * CV (control vertex, or control point) is the main fixed access to structure of curves, you can hook Locator to CV's position <code>connectAttr ($tmpControlLocator+".worldPosition[0]") ($baseCurve+".cp["+$i+"]");</code>
 +      * EP (editable point) is a relative definited structure of curve, as curve must pass through all the Editable Points, good for curve build based on passed points, after rebuild curve, the curve will not fit perfect to the editable points, it is always a rough way to initial define the curve shape
 +      * arcLen (arcLength) is measurement of the length of the curvature, good for stretch calculation of curve <code>string $curveInfo = `arclen -ch true $baseCurve`;float $len_origin=`getAttr ($curveInfo+".arcLength")`;</code>
 +      * span is the segment of the curve defined by Editable points, <code>int $seg_cnt=`getAttr ($baseCurve+".spans")`;
 +EP_count = span_cnt + 1; 
 +CP_count = span_cnt + 3;
 +</code>
 +      * parameter of curve is defining the U position (like UV poition of nurbs surface), rebuild curve into 0-1 parameter range will make read and see the point on curve position easier, or U number is always hard to mean anything ([[http://download.autodesk.com/us/maya/2010help/index.html?url=NURBS_overview_Parameterization_of_NURBS_curves_and_surfaces.htm,topicNumber=d0e228074|official ref]])
 +
 +====== General Grammar ======
 +
 +  * comment <code javascript>// single comment
 +/*
 +line 1
 +line 2
 +*/</code>
 +  * undeclare a variable, no possible, ref: http://xyz2.net/mel/mel.076.htm
 +  * eval <code javascript>
 +string $cmds="string $selected[]=`ls -sl`;print ($selected[0]+\".hellow\");"
 +eval($cmds);
 +</code>
 +  * dynamic hotkey assign <code javascript>
 +global proc setHotKey(string $curName, string $curCmd, string $curKey, string $modkey)
 +{
 +  string $cmds="string $hotKey = \`nameCommand -ann \""+$curName+"\" -c \""+$curCmd+"\"\`;hotkey -k \""+$curKey+"\" "+$modkey+" -name $hotKey;";
 +  eval($cmds);
 +
 +}
 +setHotKey("shiHome","move -rpr 0 1 0","x","-ctl");
 +</code>
 +  * array operation <code javascript>ref: http://autodesk.com/us/maya/2011help/index.htm
 +// catenate (combine) 2 arrays
 +string $string1[] = {"light1", "light2"};
 +string $string2[] = {"light3","light4","light5"};
 +stringArrayCatenate($string1, $string2);
 +// Result: light1 light2 light3 light4 light5 //
 +
 +// append array: appendStringArray(string $copyTo[], string $copyFrom[], int $copySize)
 +string $to[] = { "a", "b", "c" };
 +string $from[] = { "d", "e", "f" };
 +appendStringArray($to, $from, 2);
 +// $to == { "a", "b", "c", "d", "e" }
 +
 +// remove from an array
 +string $removeBone[] = `ls -sl -type joint`;
 +string $Skinbones[] = stringArrayRemove($removeBone, $Skinbones);
 +
 +//sort array
 +$listOfFloats={42.42, 1.2, 8.4, -3.4, -100};
 +$listOfFloats = `sort $listOfFloats`;
 +// Result: -100 -3.4 1.2 8.4 42.42 //
 +
 +//empty array
 +string $tracks[]={};
 +clear($tracks);
 +
 +//store array cmd
 +string $selected[]=`ls -sl`;
 +print $selected;
 +string $tP="string $selected[]={";
 +for($tS in $selected){$tP+=("\""+$tS+"\""+",");}
 +$tP+="};";
 +$tP=`substitute ",}" $tP "}"`;
 +print("\n"+$tP+"\n");
 +
 +//------------------------------
 +// string array operation
 +//------------------------------
 +stringArrayToString({ "red", "blue", "green" }, "");
 +// Result: redbluegreen //
 +
 +stringArrayToString({ "red", "blue", "green" }, ", ");
 +// Result: red, blue, green //
 +
 +string $array[];
 +
 +$array = stringToStringArray("red blue green", " ");
 +print ("// " + $array[0] + "\n");
 +print ("// " + $array[1] + "\n");
 +print ("// " + $array[2] + "\n");
 +// red
 +// blue
 +// green
 +</code>
 +  * multi-dimension array <code>
 +// maya mel array is 1 D array, for 2D, try matrix[][], for 3d and above, try
 +$table[]={car_4_2,plane_3_2}; // then combine with stringToStringArray and StringArrayToString method.
 +
 +// also note: matrix cant be resized once defined, so use Array creatively for multi-D array
 +</code>
 +  * string operation<code javascript>
 +// regex examples: http://ewertb.soundlinker.com/mel/mel.094.php
 +//match related operation
 +
 +// abstract match, also good for finding and check string with pattern
 + if(`gmatch $autoObj "*_L"`) { $mirrorable=1; $autoTarget = `substitute "_L" $autoObj "_R"`; }
 +
 +// pattern match
 +endsWith("abc", "bc"); // 1 true, 0 false, endsWith(string, subfix)
 +
 +// absolute compare
 +string $s1="hello";
 +string $s2="goodbye";
 +int $compare = `strcmp $s1 $s2`;
 +// Result: 1 //
 +$compare = `strcmp $s2 $s1`;
 +// Result: -1 //
 +$compare = `strcmp "hello" $s1`;
 +// Result: 0 //
 +
 +// break string
 +string $objectName="namespace:objName";
 +string $buffer[]; 
 +tokenize $objectName ":" $buffer;
 +
 +string $namespace = $buffer[0] ; // "namespace"
 +
 +// uppercase and lowercase
 +
 +tolower "UnSatIsfIEd";
 +// Result:unsatisfied//
 +toupper "UnSatIsfIEd";
 +// Result:UNSATISFIED//
 +capitalizeString("maya")
 +// Result: "Maya" //
 +
 +// search and replace substring
 +string $text = "one + two + three + four";
 +string $result = substituteAllString($text, "+", "plus");
 +print $result;
 +
 +global proc stringToChars(string $charString){
 +string $array[];
 +for($index=1; $index <= size($charString); $index++)
 +{
 +$array[$index-1] = `substring ($charString) ($index) ($index)`;
 +}
 +return $array;
 +}
 +</code>
 +  * simple sort step<code>
 +string $selected[]=`ls -sl`;
 +
 +for($i=0;$i<(size($selected)-1);$i++){
 +print $selected[$i];
 +print $selected[($i+1)];
 +if(strcmp($selected[$i],$selected[($i+1)])>0) {
 +print "small";
 +reorder -r 1 $selected[$i] ;
 +}
 +print "\n";
 +}
 +</code>
 +  * file test <code javascript>filetest -f "vortex.xpm";</code>
 +  * get env variable <code javascript>getenv XBMLANGPATH;</code>
 +  * change namespace<code javascript>namespace -mv "theNameSpace" ":" -force;</code>
 +  * try catch <code>catch( `createNode -name myTransform transform` )</code>
 +  * trace and print for debug<code javascript>
 +// trace does what print does,but has option to give where is the command
 +trace -where ();
 +
 +warning -showLineNumber 1 "Info here"; // Warning: Info here
 +
 +error "No"; // Error: No
 +
 +// get Type
 +whatIs "$aa"; // variable type
 +objectType $ball; // object type
 +</code>
 +  * get Maya system and version <code javascript>
 +float $t=float(`about -version`);
 +about -operatingSystem; // win64
 +</code>
 +
 +====== Mel with Maya objects ======
 +
 +===== selection and info related =====
 +
 +Note and Issues about Maya selection
 +
 +  - Maya does not store the vertex in selection order
 +
 +  * select none <code mel>select -cl</code>
 +  * show short name and long name of objects <code mel>ls -sl -l; ls-sl -sn;</code>
 +  * select pick navigate <code mel>pickWalk -d down;</code>
 +  * save selection and restore selection<code mel>string $select[] = `ls -sl`;
 +select -r $select;
 +for ( $node in $select )     // process each selection
 +{
 +   /* … */
 +}
 +</code>
 +  * select to shell <code>ConvertSelectionToShell;</code>
 +  * face selection to selection border (Face > Outline Edge)<code>
 +select -r `polyListComponentConversion -ff -te -bo`;
 +</code>
 +  * last item from selection <code mel>string $lastItem[] = `ls -sl -tl 1`;</code>
 +  * list vertex <code mel>ls -sl -fl
 +ls -sl -flatten  // individual list
 +ls -sl -type float3
 +</code>
 +  * list by type <code mel>ls -sl -showType</code>
 +  * list top group (transform) <code javascript>ls -as; //persp top front side Group</code>
 +  * list all sets <code mel>string $sets[]=`ls -type objectSet`;</code>
 +  * get selected masked<code mel>string $select[] = `ls -sl`;
 +// Result: pSphere1 nurbsSphereShape1 //
 +
 +filterExpand -selectionMask 12;   // Poly Mesh
 +// Result: pSphere1 //
 +
 +filterExpand -selectionMask 10;   // Nurbs Surfaces
 +// Result: nurbsSphere1;
 +Selection Mask Component Type
 +31 Polygon Vertices
 +32 Polygon Edges
 +34 Polygon Facets
 +35 Polygon UV Map Coordinates
 +46 Lattice Points
 +47 Particle Components
 +70 Polygon VtxFace
 +
 +// select all poly geo from top node
 +$allChild = `listRelatives -ad "root_node"`;
 +$allGeo = `filterExpand -selectionMask 12 $allChild`;
 +
 +</code>
 +  * get/select children/parents <code mel>string $children[] = `listRelatives -children pSphere1`; // all children
 +string $parent[] = `listRelatives -parent pSphere1`; // all parent
 +// Pick next object on same level
 +string newSelect[] = `pickWalk -direction right`;
 +// Pick previous object on same level
 +string newSelect[] = `pickWalk -direction left`;
 +// Move down to and select child
 +string newSelect[] = `pickWalk -direction down`;
 +// Move up to and select parent
 +string newSelect[] = `pickWalk -direction up`;</code>
 +  * getAllShape <code javascript>proc string[] getShapes( string $xform )
 +{
 +   string $shapes[];
 +
 +   $shapes[0] = $xform;
 +
 +   if ( "transform" == `nodeType $xform` )
 +   // If given node is not a transform, assume it is a shape
 +   // and pass it through
 +   {
 +      $shapes = `listRelatives -fullPath -shapes $xform`;
 +   }
 +
 +   return $shapes;
 +}</code>
 +  * get1stShape <code javascript>global proc string shi_getShape(string $dag)
 +{
 +string $rel[] = `listRelatives -pa -ni -s $dag`;
 +
 +if (size($rel) > 1)
 +warning("Expected a single shape under transform " + $dag +
 +" Function may not behave as expected.");
 +
 +if (size($rel) > 0)
 +$dag = $rel[0];
 +
 +return $dag;
 +}</code>
 +  * getTransform <code javascript>proc string getTransform( string $shape )
 +{
 +   string $transform = "";
 +
 +   if ( "transform" != `nodeType $shape` )
 +   // If given node is already a transform, just pass on through
 +   {
 +      string $parents[] = `listRelatives -fullPath -parent $shape`;
 +      $transform = $parents[0];
 +   }
 +
 +   return $transform;
 +}</code>
 +
 +  * polygon info mel tool <code javascript>
 +// topological information on polygonal objects
 +polyInfo -edgeToFace `ls -sl`; // -ef
 +polyInfo -vertexToFace `ls -sl`; //-vf
 +polyInfo -faceToEdge `ls -sl`; //-fe
 +polyInfo -faceToVertex(-fv); // -fv
 +polyInfo -faceNormals(-fn);
 +
 +//required counts on the specified objects.
 +polyEvaluate -f;
 +polyEvaluate -e;
 +polyEvaluate -v;
 +polyEvaluate -uv;
 +polyEvaluate -shell;
 +polyEvaluate -b; //xmin xmax ymin ymax zmin zmax, ((xmin,xmax), (ymin,ymax), (zmin,zmax))
 +polyEvaluate -b2; // uv: xmin xmax ymin ymax  ((xmin,xmax), (ymin,ymax), (zmin,zmax))
 +
 +polyEvaluate -faceComponent; //-fc : about selected
 +polyEvaluate -bc; // about selected
 +polyEvaluate -bc2; // about selected
 +
 +polyEvaluate -area; // about face area
 +polyEvaluate -worldArea;
 +
 +// bounding box method
 +getAttr pCube1.center
 +getAttr pCube1.boundingBoxCenterX
 +
 +getAttr pCube1.boundingBoxSizeZ
 +
 +
 +</code> 
 +  * get bounding box array <code mel>
 +// can take poly object and group
 +float $getBoundArray[] = `xform -q -ws -bb`; //-x,-y,-z, x,y,z
 +
 +// can take poly object and group
 +float $bbox[] = `exactWorldBoundingBox`; //-x,-y,-z, x,y,z
 +
 +// can take poly object and group
 +getAttr ("object_or_grp"+".boundingBoxMin") //-x,-y,-z
 +getAttr ("object_or_grp"+".boundingBoxMax") //x,y,z
 +
 +// require poly object input/selected, can't do group bb
 +polyEvaluate -b; // mel: -x x -y y -z z; py:(-x x) (-y y) (-z z)
 +</code>
 +  * get namespace and work with namespace <code javascript>global proc string shi_getNamespace(string $object)
 +{
 +    string $parts[];
 +    int $num = `tokenize $object "|" $parts`;
 +    $num =  `tokenize $parts[$num-1] ":" $parts`;
 +    string $namespace= "";
 +    for ($i = 0; $i < $num-1; $i++)
 +    {
 +        $namespace += ":" + $parts[$i];
 +    }
 +    if (size($namespace) == 0)
 +        $namespace = ":";
 +    return $namespace;
 +}</code>
 +  * select without worry for namespace <code javascript>
 +`ls -recursive 1 "r_hand_CTRL"`;
 +</code>
 +  * get namespace <code javascript>
 +string $objectName = "Character:r_arm_CTRL" ; // Our Object Name  
 +string $buffer[] ; // Create Empty Array To Hold Tokens  
 +tokenize $objectName ":" $buffer ; // Split $objectName by ":"  
 +
 +string $namespace = $buffer[0] ; // "Character"  
 +string $object = $buffer[1] ; // "r_arm_CTRL"
 +// simplier and more accurate
 +string $objectWithoutNamespace = $buffer[size($buffer)-1] ;  
 +</code>
 +  * get workspace <code javascript>
 +workspace -q -rd // get workspace directory
 +</code>
 +  * get current Manipulator display position<code javascript>
 +// create locator at move manipulator
 +float $moveManip[] = {};
 +// switch to translate mode
 +setToolTo $gMove;
 +// get manipulator position
 +$moveManip = `manipMoveContext -q -position Move `;
 +// create locator
 +string $locator[] = `spaceLocator -p 0 0 0`;
 +setAttr ($locator[0]+".translate") $moveManip[0] $moveManip[1] $moveManip[2];
 +</code>
 +  * get member of a set<code javascript>string $children[] = `sets -q $setName`;</code>
 +  * select all texture file node and list them<code javascript>
 +string $texes[]=`ls -type file`;
 +string $tex;
 +for ($tex in $texes){
 +    print (`getAttr ($tex+".fileTextureName")`);
 +    print "\n";
 +}
 +</code>
 +  * a true fully-tested advanced renamer
 +    * http://www.rodgreen.com/?p=117
 +
 +  * curve interaction and intersection <code mel>
 +string $intersectNode=`createNode "curveIntersect"`;
 +connectAttr -f ($wheel_link+".worldSpace[0]") ($intersectNode+".inputCurve1");
 +connectAttr -f ($wheel_circle+".worldSpace[0]") ($intersectNode+".inputCurve2");
 +string $posOnCurveNode=`createNode "pointOnCurveInfo"`;
 +connectAttr -f ($wheel_link+".worldSpace[0]") ($posOnCurveNode+".inputCurve");
 +connectAttr -f ($intersectNode+".parameter1[0]") ($posOnCurveNode+".parameter");
 +    
 +string $loc_results[]=`spaceLocator -n ($prefix+"loc_result_pos")`;
 +string $loc_result=$loc_results[0];
 +connectAttr ($posOnCurveNode+".position") ($loc_result+".t");
 +</code>code mel
 +===== object creation related =====
 +  * create object with unique name<code mel>spaceLocator -n "name#"; </code>
 +  * check object or attribute exists <code javascript>
 +int $objTest = `objExists $myObject` ; // 1 or 0
 +if(`objExists "R_Arm_Ctrl.IKFK"`) print "It Exists!" ;  
 +</code>
 +  * create camera <code mel>camera</code>
 +  * create annotation <code mel> </code>
 +  * draw curve based on locator pos <code javascript>
 +string $locArray[]=`ls -sl`;
 +$i=0;
 +$curveGenCmd="curve -d 3 ";
 +for($i=0;$i<size($locArray);$i++){        
 +    if(`objExists $locArray[$i]`){
 +        string $tmpX=`getAttr ($locArray[$i]+".tx")`;
 +        string $tmpY=`getAttr ($locArray[$i]+".ty")`;
 +        string $tmpZ=`getAttr ($locArray[$i]+".tz")`;
 +        $curveGenCmd=$curveGenCmd+"-p "+$tmpX+" "+$tmpY+" "+$tmpZ+" ";
 +    }
 +}
 +$curveGenCmd=$curveGenCmd+";";
 +eval($curveGenCmd);
 +</code>
 +  * draw polyFace based on locator pos <code javascript>
 +string $locArray[]; // after already stored
 +string $cmd = "polyCreateFacet -ch on -tx 1 -s 1";
 +for ($i=0; $i<size($locArray); $i++)
 +{
 + $xyzPos = `xform -q -ws -t $locArray[$i]`;
 + $cmd = ($cmd+" -p "+$xyzPos[0]+" "+$xyzPos[1]+" "+$xyzPos[2]+" ");
 +}
 +eval($cmd);
 +</code>
 +  * draw polyFace based on Curve (like Fill Color in illustrator) <code javascript>
 +string $selected[]=`ls -sl`;
 +string $curve=$selected[0];
 +$cvs = `getAttr ($curve+".spans")`;
 +string $cmd = "polyCreateFacet -ch on -tx 1 -s 1";
 +string $type="cv"; // cv / ep
 +if($type=="cv") $cvs+=2;
 +for ($n=0; $n<=$cvs; $n++)
 +{
 + $xyzPos = `xform -q -ws -t ($curve+"."+$type+"["+$n+"]")`;
 + $cmd = ($cmd+" -p "+$xyzPos[0]+" "+$xyzPos[1]+" "+$xyzPos[2]+" ");
 +}
 +string $newMesh[] = `eval ($cmd)`;
 +</code>
 +  * block based instance generation (select a group of object to instant, run this, you can get a window for quick instance creation) <code javascript>
 +if ( `window -exists shiBlock` ) {
 +    deleteUI shiBlock; // delete window when it exists
 +}
 +window -t "Block Lister by Shining" -wh 200 400 -mxb 0 shiBlock;
 + 
 +gridLayout  -numberOfColumns 2 -cwh 100 40;
 +string $selected[]=`ls -sl`;
 +string $children[] = `listRelatives -children $selected[0]`; 
 +int $count = size($children);
 +for($i=0;$i<$count;$i++){
 +string $buffer[] ; 
 +clear($buffer); 
 +tokenize $children[$i] ":" $buffer;  
 +$label=$buffer[(size($buffer)-1)];
 +string $tcmd="$newBlock=`instance \""+$children[$i]+"\"`;parent -w $newBlock;move -ws -a 0 0 0 $newBlock;";
 +button -l $label -c $tcmd;
 +}
 +showWindow shiBlock;
 +</code>
 +  * common ctrlShape curve creation<code>
 +curve -d 1 -p -0.3093823805 -4.440892099e-16 4.999995973e-10 -p 0.3093823805 -4.440892099e-16 4.999995973e-10 -p 5.000000414e-10 -4.440892099e-16 4.999995973e-10 -p 5.000000414e-10 0.309382381 8.499999815e-09 -p 5.000000414e-10 -0.309382381 -8.500000259e-09 -p 5.000000414e-10 -4.440892099e-16 4.999995973e-10 -p 5.000000414e-10 7.999999774e-09 -0.3093823805 -p 5.000000414e-10 -9.000000301e-09 0.3093823805 -n "locator";
 +</code>
 +  * Python sample code<code python>
 +selected=cmds.ls(sl=1)
 +deg=3
 +pos_list = [ cmds.xform(obj, q=1, ws=1, t=1) for obj in selected]
 +created = cmds.curve(d=deg, p=pos_list)
 +</code>
 +
 +===== object tranform related =====
 +  * get object position and apply transform <code mel>
 +float $pos[3] = `xform -q -ws -a -rp $object`; 
 +xform -ws -a -t $pos[0] $pos[1] $pos[2] $object2; 
 +</code>
 +  * get and move position of a vertex <code mel>xform -a -ws -t 0 0 0 pCube1.vtx[0]; // move
 +float $vtxPos[3] = `xform -q -ws -t pCube1.vtx[0]`;
 +print $vtxPos; //get </code>
 +  * create a locator at selected vertex <code mel>string $lastItem[] = `ls -sl -tl 1`;
 +float $pos[3] = `xform -q -ws -t $lastItem[0]`; 
 +spaceLocator -p $pos[0] $pos[1] $pos[2];
 +
 +// or move locator after create
 +string $lastItem[] = `ls -sl -tl 1`;
 +float $pos[3] = `xform -q -ws -t $lastItem[0]`; 
 +spaceLocator; move -a $pos[0] $pos[1] $pos[2];
 +</code>
 +  * get position and pivot position <code javascript>xform -q -ws -rp $selected[0];
 +xform -q -ws -t $selected[0];</code>
 +  * sync First selected object orientation axis to 2nd selected object <code javascript>
 +string $selected[]=`ls -sl`;
 +parent $selected[0] $selected[1];
 +makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -jointOrient $selected[0];
 +parent -w $selected[0];
 +</code>
 +  * store current orientation axis<code javascript>
 +global proc shi_loc_pivot_rot(){
 +string $selected[] = `ls -sl`;
 +string $a;
 +for($a in $selected){
 +float $pos[3] = `xform -q -ws -rp $a`;
 +float $rot[3] = `xform -q -ws -ro $a`;
 +spaceLocator; 
 +move -a $pos[0] $pos[1] $pos[2];
 +rotate -a -ws $rot[0] $rot[1] $rot[2];
 +}
 +}
 +</code>
 +  * reset transformation and avoid attribute lock <code javascript>
 +   if(!`getAttr -lock ($t+".sx")`) setAttr ($t+".sx") 1;
 +   if(!`getAttr -lock ($t+".sy")`) setAttr ($t+".sy") 1;
 +   if(!`getAttr -lock ($t+".sz")`) setAttr ($t+".sz") 1;
 +</code>   
 +  * transfer UV layout from srcModel to toModel <code javascript>
 +// object must be the same
 +string $srcNamespace = "srcModel"; // move newUV into oldModel
 +string $toNamespace = "toModel"; 
 +string $srcMesh[]=`ls -type "mesh" ($srcNamespace+":*")`;
 +for ($eachSrc in $srcMesh){
 +    string $buffer[];
 +    tokenize $eachSrc ":" $buffer;
 +    string $objName = $buffer[size($buffer)-1];
 +    if(`objExists($toNamespace+":"+$objName)`){
 +        print($toNamespace + ":" + $objName+"\n");
 +        print($eachSrc+"\n");
 +        polyTransfer -uv 1 -ao $eachSrc ($toNamespace + ":" + $objName);
 +        // identical topology, same vertex, edge, and face numbering.
 +        // uv v vc
 +    }
 +}
 +</code>
 +  * get curve length ([[http://xyz2.net/mel/mel.073.htm|ref]])<code javascript>
 +float $curveLength = `arclen $curve`;
 +
 +// If the ‘-constructionHistory’ flag is specified the command creates a "curveInfo" node downstream of the curve. This offers a persistent node which you can use to track changes to the curve.
 +
 +string $curveInfo = `arclen -ch true $curve`;
 +// Result: curveInfo1 //
 +
 +getAttr ( $curveInfo + ".arcLength" );
 +// Result: 5.335323 //
 +
 +move -r -os -wd 0 0 1.0 ( $curve + ".cv[1]" );
 +
 +getAttr ( $curveInfo + ".arcLength" );
 +// Result: 4.309423 //
 +</code>
 +  * stop inherit parent transform <code>
 +inheritTransform -off $ball;
 +</code>
 +  * copy transformation from A to B<code>
 +string $selected[] = `ls -sl`;
 +print ($selected[0]+" is positioned at "+$selected[1]+"\n");
 +float $pos[3] = `xform -q -ws -t $selected[1]`;xform -t $pos[0] $pos[1] $pos[2] $selected[0];
 +float $pos[3] = `xform -q -ws -ro $selected[1]`;xform -ro $pos[0] $pos[1] $pos[2] $selected[0];
 +
 +// simple way
 +parent -r $grp $child;  // xform -q all
 +parent -w $grp; // xform all
 +</code>
 +
 +**locator and inform sampling**
 +
 +  * shi_loc_4in1_pose (orient obj in aim, facing, siding) <code mel>
 +global proc string shi_loc_4in1_pose(){
 +print("\n\nselect 4 object center(left right), aim and up)\n");
 +string $object[] = `ls -sl -fl`;
 +
 +float $crdFront[] = `xform -q -ws -t $object[0]`;
 +float $crdBack[] = `xform -q -ws -t $object[1]`;
 +float $crdLoc[];
 +$crdLoc[0] = ($crdFront[0] + $crdBack[0]) /2;
 +$crdLoc[1] = ($crdFront[1] + $crdBack[1]) /2;
 +$crdLoc[2] = ($crdFront[2] + $crdBack[2]) /2;
 +string $locs[] = `spaceLocator`;
 +move -ws $crdLoc[0] $crdLoc[1] $crdLoc[2] $locs[0];
 +string $cst[] = `aimConstraint -offset 0 0 0 -weight 1 -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "object" -worldUpObject $object[3] $object[2] $locs[0]`;
 +delete $cst;
 +return $locs[0];
 +}
 +</code>
 +  * aim by AimLoc-AimAxis, 2ndDirLoc-2ndDirAxis (Up) <code mel>aimConstraint -offset 0 0 0 -weight 1 -aimVector 0 1 0 -upVector 0 0 1 -worldUpType "object" -worldUpObject $dir2ndLoc $aimLoc $obj;</code>
 +===== Transform tool related =====
 +
 +  * move tool<code javascript>
 +// get move tool option example
 +manipMoveContext -q -orientJointEnabled Move
 +// set move tool option example
 +manipMoveContext -e -orientJointEnabled 0 Move;
 +</code>
 +
 +===== Common Mel Tool =====
 +
 +==== system detection ====
 +
 +  * add custom folder to script path, so sourcing the name directly can run the script <code javascript>
 +$old_path = `getenv "MAYA_SCRIPT_PATH"`;
 +putenv "MAYA_SCRIPT_PATH" ($old_path +";D:/myCustomScriptPath/;");
 +</code>
 +
 +  * detect os and source file <code javascript>
 +global proc loadScript(string $path){
 +    string $command = "source \""+$path+"\"";  
 +    eval $command ;  
 +}
 +//-------------------------------------
 +string $z_sys="";
 +
 +// check os
 +// check os
 +string $checkOS = `about -os`;
 +if($checkOS == "windows" || $checkOS == "win64" ) $z_sys=system("echo %z_sys%"); // windows
 +else $z_sys=system("printf $z_sys"); // linux, osx (bash,csh) echo do the name but with new line
 +
 +// remove new line
 +$a=stringToStringArray($z_sys,"\r"); // windows echo use \r newline
 +$aS=stringArrayToString($a,"");
 +$a=stringToStringArray($aS,"\n"); // linux echo use \n newline
 +$z_sys=$a[0];
 +
 +$z_sys = substituteAllString($z_sys, "\\", "/"); // to normal directory format for windows
 +
 +// make sure system environment got defined
 +if($z_sys!="") print $z_sys;
 +
 +// another simple way is to use mel command to get z_system variable
 +$z_sys=`getenv "z_sys"`;
 +
 +//-------------------------------------
 +string $rootPath=$z_sys+"/../dev/melTool/v1.0.3/";
 +loadScript($rootPath+"shiFun_info.mel");
 +</code>
 +  * path format that works for both win, linux(mac) <code javascript>
 +global string $rootPath="/user_data/dev/melTool/v1.0.3/"; // linux, mac
 +global string $rootPath="D:/z_sys/xTool/resMaya/scripts/"; // windows
 +</code>
 +
 +  * get Maya version as float number <code javascript>
 +global proc float getMayaVersionAsFloat(){
 +    float $version=2012;
 +    if (`exists getApplicationVersionAsFloat`) return `getApplicationVersionAsFloat`;
 +    string $versionString=`about -v`;
 +    string $tempString[];
 +    string $char;
 +    tokenize $versionString $tempString;
 +    //default to 2012, if versionString is not all numbers
 +    for ($i=0;$i<size($tempString[0]);$i++){
 +        $char=`substring $tempString[0] ($i+1) ($i+1)`;
 +        if (!`gmatch $char "[0-9]"`) return 2012;
 +    }
 +    $version=$tempString[0];
 +    return $version;
 +}
 +if (`getMayaVersionAsFloat`<2012) $iconExt="xpm"; // none one use 2012
 +</code>
 +  * get script's own location, with this function inside <code javascript>
 +// Fully auto install, with Python script name inside this file name as "install_PythonFileName.mel"
 +global proc Tool_Locator (){} // a catcher empty functon for get cmd path
 +global proc string[] Tool_Location_v2 (){
 +    string $whatIs=`whatIs Tool_Locator`; // actual main dir path get function
 +    string $fullPath=`substring $whatIs 25 999`;
 +    string $buffer[];
 +    int $numTok=`tokenize $fullPath "/" $buffer`;
 +    int $numLetters=size($fullPath);
 +    int $numLettersLastFolder=size($buffer[ $numTok - 1 ]);
 +    string $scriptLocation=`substring $fullPath 1 ($numLetters-$numLettersLastFolder)`;
 +    string $script_name_mel = $buffer[ $numTok - 1 ];
 +    string $bufferB[];
 +    int $numTokB=`tokenize $script_name_mel "_." $bufferB`;
 +    string $script_name = $bufferB[ $numTokB - 2 ];
 +    return {$scriptLocation,$script_name};
 +}
 +string $tool_info[] = `Tool_Location_v2`; // file path, file name without extension
 +</code>
 +
 +==== File operation ====
 +
 +  * load object <code javascript>catch(`loadPlugin "objExport.mll"`);</code>
 +  * load plugin <code>if(`pluginInfo -q -loaded "fbxmaya"` == 1) print "loaded";</code>
 +  * file obj export <code javascript>// import eps
 +file -import -type "EPS" -mnc false -rpr "TMP_" -options "sc=1.1;group=on" "D:/z01_txt_v002.eps";
 +
 +// export selected to obj
 +file -f -options "groups=1;ptgroups=1;materials=1;smoothing=1;normals=1" -typ "OBJexport" -pr -es "D:/zTxt_001_obj.obj";
 +
 +// export selected to mb
 +file -f -options "v=0;" -typ "mayaBinary" -pr -es "D:/zTxt_KS_z01_v001.mb";
 +</code>
 +  * get current mel working directory, normally the maya startup directory in cmd, used by chdir, system, fopen, and popen cmd <code javascript>pwd</code>
 +  * get workspace directory, normally defined by set project cmd <code javascript>workspace -q -dir</code>
 +  * workspace set <code javascript>workspace -dir "C:/Users"</code>
 +  * workspace in python <code python>
 +cmds.workspace (dir='C:/Users')
 +
 +startingDir = cmds.workspace(q=True, rootDirectory=True)
 +destDir = QtGui.QFileDialog.getExistingDirectory(None,'Open working directory', startingDir, QtGui.QFileDialog.ShowDirsOnly)
 +
 +startingDir = 'C:/Program Files'
 +dialog = QtGui.QFileDialog()
 +dialog.setFileMode( QtGui.QFileDialog.FileMode() )
 +dialog.getExistingDirectory( None, 'Open working directory', startingDir )
 +
 +dialog.getOpenFileName( None, 'Open working directory', startingDir )
 +
 +os.startfile(startingDir)
 +</code>
 +
 +==== modeling mel tool ====
 + 
 +<code mel>
 +//select mode
 +SelectVertexMask
 +SelectEdgeMask
 +SelectFacetMask
 +SelectToggleMode
 +
 +updateLockSelectionIcon; // select lock
 +
 +// display mode
 +ToggleBackfaceGeometry;
 +DisplayWireframe;
 +DisplayShaded;
 +ToggleFaceNormalDisplay;
 +
 +ShowManipulatorTool;
 +
 +//mirror x
 +
 +//delete history
 +delete -ch;
 +
 +// bevel plus for curves
 +bevelPlus -ch 1 -js 1 -tol 0.01 -ns 4 -cap 4 -width 0.1 -depth 0.1 -ed 0.5 -bevelInside 0 -outerStyle 2 -innerStyle 2 -polygon 1 -no 1 -polyOutMethod 2 -polyOutExtrusionType 3 -polyOutExtrusionSamples 2 -polyOutCurveType 3 -polyOutCurveSamples 6 -polyOutUseChordHeightRatio 0 `ls -sl`;
 +
 +// rebuild with reduce for curves
 +rebuildCurve -ch 1 -rpo 1 -rt 1 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s 4 -d 3 -tol 0.9 `ls -sl`;
 +</code>
 +
 +^Loop |SplitEdgeRingTool |
 +^Brid |performPolyBridgeEdge 0 |
 +^Extr |performPolyExtrude 0 |
 +^Fill |FillHole |
 +^Spli |SplitPolygonTool |
 +^AveV |performPolyAverageVertex 0 |
 +^Cetr |MergeToCenter |
 +^Save |SaveScene |
 +^-0- |setAttr \"testMat.transparency\" -type double3 1 1 1 |
 +^-7- |setAttr \"testMat.transparency\" -type double3 0.7 0.7 0.7 |
 +^-%- |setAttr \"testMat.transparency\" -type double3 0 0 0 |
 +
 +==== scripting mel tool ====
 +
 +  * check what is the command source code<code mel> 
 +// check where is the command
 +whatIs ScriptEditor; // check what is the ScriptEditor command
 +
 +// if the result shows the file name, that means, the source code is there.
 +// if the result says "RunTimeCommand", check Hotkey Editor, the source code is there under its name. or use this cmd
 +runTimeCommand -q -c "PasteVertexSkinWeights";
 +
 +// if the result says "Command", it is C++ compiled maya command or built-in maya command which written in C++.
 +</code>
 +
 +  * scripting history related <code mel>
 +// toggle echo history
 +handleScriptEditorAction "echoAllCommands";
 +
 +// scriptEditor clear upper
 +cmdScrollFieldReporter -e -clear $gCommandReporter;
 +</code>
 +
 +  * script running time related <code javascript>
 +// beginning of code
 +$startTime = `timerX`;
 +
 +// process code here
 +
 +// end of code
 +$totalTime = `timerX -startTime $startTime`;
 +print ("\nTotal Time: "+$totalTime); // it is in seconds
 +</code>
 +
 +  * get selected attributes <code javascript>
 +// one line code
 +$attrs = `selectedChannelBoxPlugs`;
 +
 +// actual code of that function, It reads object attr, shape attr, history attr, 
 +string $main[], $mainObjects[];
 +string $shape[], $shapeObjects[];
 +string $history[], $historyObjects[];
 +string  $outputs[], $outputObjects[];
 +
 +$main = `channelBox -q -selectedMainAttributes $gChannelBoxName`;
 +$shape = `channelBox -q -selectedShapeAttributes $gChannelBoxName`;
 +$history = `channelBox -q -selectedHistoryAttributes $gChannelBoxName`;
 +$outputs = `channelBox -q -selectedOutputAttributes $gChannelBoxName`;
 +
 +string  $attr;
 +
 +$main = `channelBox -q -selectedMainAttributes $gChannelBoxName`;
 +$mainObjects = `channelBox -q -mainObjectList $gChannelBoxName`;
 +
 +$shape = `channelBox -q -selectedShapeAttributes $gChannelBoxName`;
 +$shapeObjects = `channelBox -q -shapeObjectList $gChannelBoxName`;
 +
 +$history = `channelBox -q -selectedHistoryAttributes $gChannelBoxName`;
 +$historyObjects = `channelBox -q -historyObjectList $gChannelBoxName`;
 +
 +$outputs = `channelBox -q -selectedOutputAttributes $gChannelBoxName`;
 +$outputObjects = `channelBox -q -outputObjectList $gChannelBoxName`;
 +
 +if( size( $main ) > 0 ) {
 + for( $object in $mainObjects ) {
 + for ($mattr in $main) {
 + $result[ size($result) ] = ($object+"."+$mattr);
 + }
 + }
 +}
 +
 +if( size( $shape ) > 0 ) {
 + for( $object in $shapeObjects ) {
 + for ($mattr in $shape) {
 + $result[ size($result) ] = ($object+"."+$mattr);
 + }
 + }
 +}
 +
 +if( size( $history ) > 0 ) {
 + for( $object in $historyObjects ) {
 + for ($mattr in $history) {
 + $result[ size($result) ] = ($object+"."+$mattr);
 + }
 + }
 +}
 +
 +if( size( $outputs ) > 0 ) {
 + for( $object in $outputObjects ) {
 + for ($mattr in $outputs) {
 + $result[ size($result) ] = ($object+"."+$mattr);
 + }
 + }
 +}
 +</code>
 +==== material and hypershade mel tool ====
 +
 +  * connect nodes<code mel>
 +connectAttr node1.attrA node2.attrB
 +connectAttr -f node1.attrA node2.attrB //force connection
 +</code>
 +  * batch material creation and texture linking <code javascript>
 +int $i=10;
 +print $i;
 +$i++;
 +$newMat=`shadingNode -asShader blinn`;
 +$newTex=`shadingNode -asTexture file`;
 +setAttr -type "string" ($newTex+".fileTextureName") ("/robot/maya/sourceimages/v04/sepiaRobot_Diffuse.10"+$i+".tif");
 +connectAttr -f ($newTex+".outColor") ($newMat+".color");
 +rename $newMat ("robotMat"+$i);
 +rename $newTex ("robotTex"+$i);
 +</code>
 +  * distanceBetween node, auto create distance measurer between 2 object <code>
 +global proc createDistanceNodeFromTwo(){
 +string $selected[]=`ls -sl`;
 +string $newDist=`shadingNode -asUtility distanceBetween`;
 +string $dname =$selected[0] +"_distanceBetween";
 +rename $newDist $dname;
 +//connectAttr -f (`shi_getShape $selected[0]`+".worldPosition[0]") ($dname+".point1"); // for locator only
 +//connectAttr -f (`shi_getShape $selected[1]`+".worldPosition[0]") ($dname+".point2");
 +connectAttr -f ($selected[0]+".t") ($dname+".point1");
 +connectAttr -f ($selected[1]+".t") ($dname+".point2");
 +connectAttr -f ($selected[0]+".parentMatrix") ($dname+".inMatrix1");
 +connectAttr -f ($selected[1]+".parentMatrix") ($dname+".inMatrix2");
 +}
 +</code>
 +  * setRange, animCurve, clamp: range mapping and linear or non-linear data value mapper <code mel>
 +shadingNode -asUtility setRange;
 +// Result: setRange1 // 
 +shadingNode -asUtility clamp;
 +// Result: clamp1 // 
 +
 +createNode animCurveUU;
 +setKeyframe -f 0 -v 0;
 +setKeyframe -f 1 -v 1;
 +
 +//ref: http://download.autodesk.com/us/maya/2011help/Nodes/animCurve.html
 +
 +// read and access this animCurve node:
 +// http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/mel/DATA_anim_curves.html
 +
 +animCurveTL time distance
 +animCurveTA time angle
 +animCurveTT time time
 +animCurveTU time double
 +animCurveUL double distance
 +animCurveUA double angle
 +animCurveUT double time
 +animCurveUU double double
 +</code>
 +
 +==== Rigging mel tool ====
 +  * display local rotation axis <code javascript>setAttr ("MyJoint"+".displayLocalAxis") 1;</code>
 +  * override display color<code python>
 +# python
 +node = cmds.ls(sl=1)[0]
 +colorIndex = 1
 +cmds.setAttr(node+'.overrideEnabled',1)
 +cmds.setAttr(node+'.overrideColor', colorIndex)
 +# node, the transform node and shape node can have different override setting, so make sure you choose the right one you want
 +# color index
 +0,1,2,3: grey, black, dark grey, light grey
 +4,5,6: dark red blue, light blue
 +7,8: dark green, purple
 +9: magenta, 
 +10,11,12: dark orange, brown, light brown
 +13,14,15: bright red, green, blue
 +16,17,18,19,20,21: white, yellow, cyan, green, pink, brown, 
 +22,23,24, middle yellow, green, brown, 
 +29-31 mud, mud green, mud deep green, mud blue, mud deep blue, mud purple, mud red
 +orange: 11
 +cyan:18
 +pink: 20
 +
 +</code>
 +  * un-template all the mesh or template all the mesh<code javascript>
 +string $mesh[]=`ls -sl -type transform`;
 +string $mesh[]=`ls -sl`;
 +
 +int $i=0;
 +int $n=0;
 +for($i=0; $i<size($mesh);$i++){ 
 +CBdeleteConnection ($mesh[$i]+".overrideEnabled");
 +setAttr -lock false ($mesh[$i]+".overrideEnabled");
 +setAttr -lock false ($mesh[$i]+".overrideDisplayType");
 +setAttr ($mesh[$i]+".overrideEnabled") 0;
 +setAttr ($mesh[$i]+".overrideDisplayType") 0;
 +if(`exists ($mesh[$i]+"Shape")`){
 +    setAttr -lock false ($mesh[$i]+"Shape.overrideEnabled");
 +    setAttr -lock false ($mesh[$i]+"Shape.overrideDisplayType");
 +    setAttr ($mesh[$i]+"Shape.overrideEnabled") 0;
 +    setAttr ($mesh[$i]+"Shape.overrideDisplayType") 0;
 +}
 +else {print ($mesh[$i]+"Shape");print "\n ";print $n;print "\n";$n++;}
 +}
 +// improve can be done
 +// 1. no group detection; 2. no bad named shape node detection
 +</code>
 +  * delete constrains <code>
 +string $constrain[]=`ls -sl`;
 +for($i=0;$i<size($constrain);$i++){
 +    if(objectType($constrain[$i])=="parentConstraint") {delete $constrain[$i];print $constrain[$i];print "\n";}
 +    else if(objectType($constrain[$i])=="orientConstraint") {delete $constrain[$i];print $constrain[$i];print "\n";}
 +    else if(objectType($constrain[$i])=="pointConstraint") {delete $constrain[$i];print $constrain[$i];print "\n";}
 +}
 +</code>
 +  * create constrains <code javascript>
 +select -r ($legSide + "HipFK") ;
 +select -tgl ($legSide + "Hip") ;
 +orientConstraint -offset 0 0 0 -weight 1;
 +
 +poleVectorConstraint -weight 1;// PV constrain
 +</code>
 +  * additional constrain plugin:
 +    * decomposeMatrix (like Parent+Scale constrain)<code>createNode decomposeMatrix;
 +//ref: http://www.sigillarium.com/blog/lang/en/186/
 +</code>
 +  * visibility switch (expression)<code javascript>lod02.visibility=(mainCtrl.lod==1);
 +lod01.visibility=(mainCtrl.lod==0);</code>
 +
 +  * data sampling
 +    * curve length and position <code>
 +float $pos[3]=`pointOnCurve -top true -pr ($i*1.0/$CurveBone_cnt) -p $tC`;
 +</code>
 +    * distance
 +  * skinCluster and weight related<code javascript>
 +// get all the skin cluster in the scene
 +ls -type "skinCluster"
 +
 +// get affected geo
 +skinCluster -q -g "skinCluster1"
 +
 +// bind
 +// bind skin for fixed parts
 +    select -r $tj;
 +    select -add $fix_geo_list;
 +    SmoothBindSkin;
 +
 +// bind
 +select -cl;
 +select -add ("bar_up_"+$i+"_env") ("bar_mid_"+$i+"_env") ("bar_low_"+$i+"_env") ("bar_btm_"+$i+"_env");
 +select -add $bar_geo_list[$i];
 +skinCluster -tsb -ih -mi 3 -omi false -dr 4 -rui false -name ("skinCluster_bar_"+$i);
 +
 +string $SelectedMesh[] = `ls -sl -fl`;
 +string $SourceSkin = `findRelatedSkinCluster $SelectedMesh[0]`;
 +string $Skinbones[] = `skinCluster -q -wi $SelectedMesh[0]` ; // list non-zero weight bones
 +string $Skinbones[] = `skinCluster -q -inf $SelectedMesh[0]` ; // list all weight bones
 +
 +print $Skinbones;print (size($Skinbones)); 
 +
 +// one line bind all geo in selection with bones in selection
 +$tmpAll = `ls -sl`;
 +$tmpBones = `ls -sl -type joint`;
 +$tmpGeos = stringArrayRemove($tmpBones, $tmpAll);
 +for($each in $tmpGeos) skinCluster -n ($each+"_skinCluster") -tsb $tmpBones $each;
 +
 +// skincluster normalize method
 +1. post: weight can go beyond 1, then affect based on total average
 +2. interactive: move on the fly, stay as 1
 +ref: http://chrislesage.com/character-rigging/how-to-stop-collapsing-vertices-in-maya-post-normalization/
 +
 +// normalize weight
 +doNormalizeWeightsArgList 1 {"4"};
 +
 +// back to bind pose
 +dagPose -reset -name bindPose1; // the bindPose node
 +</code>
 +  * ik creation <code>
 +string $selected[]=`ikHandle -sol ikRPsolver -sj $IKstart -ee $IKend`;
 +string $curIKhandle=$selected[0];
 +rename $curIKhandle ($skiBuild_prefix+"ik_handle");
 +</code>
 +  * get Contraint weight attribute like w0, w1<code>
 +$userAttr=`listAttr -ud $curLink`; // a way to get w0, w1, w2 from *Contraint object</code>
 +
 +  * fix copy skin weight function not working in Maya in 2012, when there are objects with same short name in outliner <code javascript>
 +// Error: file: /apps/Linux64/aw/maya2012/scripts/others/findSkinClusterFromSelectedComponent.mel line 44: Could not find skin cluster node. // 
 +
 +// problem: copy skin weight give error saying can't find skinCluster since their code cant deal with 2 same short name in scene
 +// solution: by tracing the error, I found their code of line 35, the Mesh related in short name instead of long time
 +
 +string $selMesh[] = `listRelatives -shapes -ni $selElems[0]`; // original line 35
 +// which instead of returning group2|pCube1|pCubeShape1 ; it returns pCubeShape1, which there is another group1|pCube1|pCubeShape1 ;
 +
 +// corrected line 35
 +string $selMesh[] = `listRelatives -shapes -ni -pa $selElems[0]`;// full path returned
 +</code>
 +==== animation mel tool ====
 + 
 +  * timeline navigation <code mel>
 +currentTime 1
 +
 +NextFrame
 +PreviousFrame
 +
 +$pSolverRootFrame = `currentTime -q`;
 +$pSolverFrameStart = `playbackOptions -q -min`;
 +$pSolverFrameEnd = `playbackOptions -q -max`;
 +$pSolverFrameIncrement = `playbackOptions -q -by`;
 +</code>
 +  * keyframe <code>
 +keyframe -query -name ($ball+".tx"); // return linked node.
 +`isAnimCurve($nodes[0])` // check if anim curve
 +listAnimatable $ball; // return all attributes that keyable
 +keyframe -time 250 -query -eval ($ball+".tx"); // sample value at time on AnimCurve
 +</code>
 +  * animation curve <code>
 +setInfinity -q -preInfinite ($ball+".tx");
 +setInfinity -preInfinite "cycle" ($ball+".tx");
 +setInfinity -postInfinite "linear" ($ball+".tx"); // constant, linear, cycle, cycleRelative, oscillate
 +
 +setKeyframe -time 1 -value -5 ($ball+".tx");
 +setKeyframe -time 48 -value 5 ($ball+".tx");
 +setKeyframe -insert -time 24 ($ball+".tx"); // add a key without change
 +keyframe -q -keyframeCount ($ball+".tx"); // return number of keys on the curve
 +
 +// other key ref: http://download.autodesk.com/us/maya/2010help/Commands/keyframe.html
 +keyframe -edit -time 48 -timeChange 20 ($ball+".tx"); // move key from f48 to f20, -absolute/-relative 
 +keyframe -edit -time 25 -valueChange 2 ($ball+".tx"); // move key value to 2, -absolute/-relative
 +
 +// edit keys by key index, like key array index
 +keyframe -edit -index 0 -index 1 -relative -timeChange 10 ($ball+".tx"); // push value of 1st,2nd key up 10
 +// edit keys by frame range
 +keyframe -edit -time "0:12" -relative -valueChange 5 ($ball+".tx"); // or :20 or 20: or : for bound range
 +keyframe -edit -index "1:20" -valueChange 3 ($ball+".tx"); // key 2 to key 21 change
 +
 +// get time of indexed key
 +keyframe -index 0 -q -timeChange ($ball+".tx"); // get frame of 1st key
 +
 +// scale key range
 +scaleKey -timePivot 5 -time ":" -valueScale 0.5 ($ball+".tx");
 +scaleKey -timeScale 0.5 ($ball+".tx");
 +
 +setDrivenKeyframe -driverValue 0 -value 0 -currentDriver ($ball+".tx") ($box+".tx"); // creation
 +setDrivenKeyframe -driverValue 2 -value 10 ($box+".tx"); // add
 +
 +// align key on int frame
 +snapKey -timeMultiple 1 ($ball+".tx"); // 1 frame interval snap
 +
 +// normal key and breakdown key, prime key vs procedure key
 +keyframe -time 1 -breakdown true ($ball+".tx");
 +
 +// key tangents: (int, out) type, angle,weighting, locking 
 +keyTangent -index 0 -outTangentType flat -inTangentType spline ($ball+".tx"); 
 +</code>
 +  * copy and paste key <code>
 +copyKey -index 0 ($ball+".tx");
 +pasteKey -time 12 -option insert ($ball+".tx");
 +cutKey -index 1 -option keys ($ball+".tx");
 +</code>
 +
 +
 +**Expression linking and Rigging mel**
 +<code mel>
 +// create a expression
 +expression -s "battery01.ty=batteryCover.rx/10.0*(-0.5);"  -o battery01 -n "expBattery01move" -ae 1 -uc all ;
 +
 +// update a expression
 +expression -e -s "battery01.ty=batteryCover.rx/10.0*(-0.5);"  -o battery01 -ae 1 -uc all expBattery01move;
 +
 +//delete a expression
 +delete expBattery01move;
 +</code>
 +  * force a mel scripted animation refresh <code>dgdirty -a;</code>
 +==== camera mel tool ====
 +   * Now you can just press down and hold \ key, and use middle mouse to 2D pan and right mouse to 2D zoom 
 +<code mel>
 +// pan image plane
 +// -down
 +
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`;
 +float $verticalFilmOffset = `getAttr ($camera + ".verticalFilmOffset")`;
 +setAttr  ($camera+ ".verticalFilmOffset" ($verticalFilmOffset - 0.02) ;
 +print ($camera + ".verticalFilmOffset = " +($verticalFilmOffset - 0.02) + "\n"); 
 +
 +// -home
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`;
 +setAttr  ($camera + ".verticalFilmOffset") 0.0;
 +setAttr  ($camera +".horizontalFilmOffset") 0.0;
 +setAttr  ($camera + ".overscan" 1.0 ; 
 +
 +// -in
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`; float $overscan =
 +`getAttr ($camera + ".overscan")`; setAttr  ($camera + ".overscan")
 +($overscan - 0.1) ; print ($camera + ".overscan = " + ($overscan - 0.1)  +
 +"\n");
 +
 +// -left
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`;
 +float $horizontalFilmOffset = `getAttr ($camera + ".horizontalFilmOffset")`;
 +setAttr ($camera + ".horizontalFilmOffset" ($horizontalFilmOffset - 0.02) ;
 +print ($camera +".horizontalFilmOffset = " + ($horizontalFilmOffset - 0.02)  + "\n"); 
 +
 +// -out
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`; float $overscan =
 +`getAttr ($camera + ".overscan")`; setAttr  ($camera + ".overscan")
 +($overscan + 0.1) ; print ($camera + ".overscan = " + ($overscan + 0.1)  +
 +"\n"); 
 +
 +// -right
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`;
 +float $horizontalFilmOffset = `getAttr ($camera + ".horizontalFilmOffset")`;
 +setAttr ($camera + ".horizontalFilmOffset" ($horizontalFilmOffset + 0.02) ;
 +print ($camera +".horizontalFilmOffset = " + ($horizontalFilmOffset + 0.02)  + "\n"); 
 +
 +// -up
 +string $currentPanel = `getPanel -up`;
 +string $camera = `modelPanel -q -camera $currentPanel`;
 +float $verticalFilmOffset = `getAttr ($camera + ".verticalFilmOffset")`;
 +setAttr  ($camera+ ".verticalFilmOffset" ($verticalFilmOffset + 0.02) ;
 +print ($camera + ".verticalFilmOffset = " +($verticalFilmOffset + 0.02 ) + "\n"); 
 +</code>
 +==== window mel tool ====
 +
 +=== Windows and Its UIs===
 +
 +<code mel>
 +// maya windows
 +ScriptEditor;
 +OutlinerWindow;
 +DisplayLayerEditorWindow;
 +toggleUIComponentVisibility "Channel Box / Layer Editor"
 +GraphEditor;
 +HypershadeWindow;
 +
 +// render
 +PlayblastWindow;
 +RenderViewWindow;
 +unifiedRenderGlobalsWindow;
 +renderWindowRender redoPreviousRender renderView;
 +BatchRender;
 +
 +// animation
 +toggleUIComponentVisibility "Time Slider";
 +toggleUIComponentVisibility "Range Slider";
 +PreferencesWindow;
 +SetProject; // set project window
 +file import; // import window
 +
 +// layout
 +setNamedPanelLayout "Four View";
 +
 +// advanced window
 +ReferenceEditor;
 +mentalrayApproxEditor;
 +</code>
 +
 +  * get modelPanel camera name (run in shelf button, or it will not work in script editor) <code>
 +$panel=`getPanel -withFocus`;
 +$curCamShape=`modelPanel -q -cam $panel`;
 +$curCam="";
 +if( `nodeType $curCamShape` == "camera" )
 +{
 + $curCam=getTransform($curCamShape);
 +}
 +</code>
 +
 +  * get window layout and its child UIs <code>
 +global proc string findWindowLayout( string $windowUI )
 +{
 +  string $controls[] = `lsUI -l -controlLayouts`;
 +  string $pattern = $windowUI + "*";
 +  string $layout = "";
 +  for ( $ui in $controls )
 +  {
 +    if ( `gmatch $ui $pattern` )
 +    {
 +      string $tokens[];
 +      int $numTokens = `tokenize $ui "|" $tokens`;
 +      if ( $numTokens > 1 )
 +      {
 +        $layout = $tokens[0] + "|" + $tokens[1];
 +        break;
 +      }
 +    }
 +  }
 +  return $layout;
 +}
 +
 +string $render_layout = findWindowLayout( "unifiedRenderGlobalsWindow" );
 +print($render_layout);
 +
 +// dig into its child uis
 +string $ca[] = `layout -q -childArray $render_layout`;
 +print($ca);
 +//rgMainForm
 +string $ca[] = `layout -q -childArray "rgMainForm"`;
 +// rendererPlusLayerLayout tabForm rgCloseBtn
 +// continues
 +
 +// query width and change layout size
 +layout -q -w ($render_layout+"|rgMainForm|tabForm|arnoldTabLayout|arnoldAOVsTab|arnoldAOVsScrollLayout");
 +// layout -e -width 800 -height 800 ($render_layout+"|rgMainForm|tabForm|arnoldTabLayout|arnoldAOVsTab|arnoldAOVsScrollLayout");
 +</code>
 +==== Menu ====
 +
 +  * get main window and attach menu <code javascript>
 +global string $custom_menu;
 +if (`menu -exists $custom_menu`) deleteUI $custom_menu;
 +     
 +global string $gMainWindow;
 +string $name="Custom";
 +$custom_menu = `menu -p $gMainWindow -to true -l $name`; // create menu, that can tear-off
 +
 +menuItem -p $custom_menu -l "About Me" -c "print \"Cool!\"";
 +</code>
 +
 +
 +==== HUD mel tool ====
 +
 +  * Head-up-display tools <code javascript>
 +if(`headsUpDisplay -ex myHUD`) headsUpDisplay -rem myHUD;
 +</code>
 +
 +  * example and ref
 +    * watch attributes: http://mayastation.typepad.com/maya-station/2010/01/watch-attribute-values-in-the-hud.html
 +==== maya preference setup ====
 +
 +  * get maya script path <code>getenv MAYA_SCRIPT_PATH;</code>
 +  * mel path var and python sys var <code javascript>
 +// maya path var operation
 +string $mayaScriptPaths[];
 +string $mayaScriptPath = `getenv MAYA_SCRIPT_PATH`;
 +tokenize $mayaScriptPath ":" $mayaScriptPaths;
 +
 +//Removing any paths that don't exist:
 +for ($pathToCheck in $mayaScriptPaths)
 +{
 +  if (!`filetest -d $pathToCheck`)
 +  $mayaScriptPaths = stringArrayRemove({$pathToCheck}, $mayaScriptPaths);
 +}
 +
 +$mayaScriptPaths = stringArrayRemove({$path}, $mayaScriptPaths);
 +stringArrayInsertAtIndex(0, $mayaScriptPaths, $path);
 +$mayaScriptPath = stringArrayToString ($mayaScriptPaths, ":");
 +putenv MAYA_SCRIPT_PATH $mayaScriptPath;
 +
 +// sys path var operation
 +python ("if '" + $path + "' in sys.path: sys.path.remove ('" + $path + "')");
 +python ("sys.path.insert ( 0, '" + $path + "')");
 +
 +</code>
 +<code javascript>
 +// APSC 1.5x crop DSLR (inch)
 +optionVar -floatValue cameraHorizAper 0.929;
 +optionVar -floatValue cameraVertAper 0.618;
 +
 +// maya unit
 +optionVar -sv "workingUnitLinear" "cm" ;
 +
 +// maya version
 +about -f
 +
 +// getenv "varName"
 +
 +// load maya rc file
 +if ( `filetest -r $myScriptFile` ) eval( "source \""+$myScriptFile+"\";" );
 +
 +optionVar -sv "ViewImageDir" "xn_view";
 +optionVar -sv "ViewSequenceDir" "djv_view";
 +optionVar -sv "ViewImageCmdFormat" "%f %s-%e";
 +optionVar -sv "ViewSequenceCmdFormat" "%f %s-%e";
 +</code>
 +===== Render related scripting =====
 +  * quick tool to turn curve render-friendly
 +    * http://www.ldaustinart.com/paul/index.php?cat=scripts&type=maya
 +
 +====== Maya GUI scripting ======
 +===== Maya UI interaction =====
 +
 +  * layer panel <code> //built-in functions
 +global proc layerEditorLayerButtonVisibilityChange(string $layer)
 +{
 + int $visible = `getAttr ($layer + ".visibility")`;
 + if (0 == $visible) $visible = true;
 + else $visible = false;
 + setAttr ($layer + ".visibility") $visible;
 +}
 +
 +global proc layerEditorLayerButtonTypeChange(string $layer)
 +{
 + int $type = `getAttr ($layer + ".displayType")`;
 +
 + if (0 == $type) $type = 1;
 + else if (1 == $type) $type = 2;
 + else $type = 0;
 +
 + setAttr ($layer + ".displayType") $type;
 +}
 +
 +global proc layerEditorLayerButtonRenderabilityChange(string $layer)
 +{
 + int $renderable = `getAttr ($layer + ".renderable")`;
 +
 + if (0 == $renderable) $renderable = true;
 + else $renderable = false;
 + setAttr ($layer + ".renderable") $renderable;
 +}
 +</code>
 +===== basic UI elements =====
 +  * elements <code javascript>
 +// button
 +button -l "Do It" -c "print \"do it\"";
 +
 +// dash line for seperation
 +separator -style "in" -hr false;
 +separator -st "none";
 +
 +//text
 +text -label "Default";
 +
 +// shelf button
 +shelfButton
 +-visible 1
 +-l "tMat"
 +-c "select -r \"testMat\""
 +-dcc "HypershadeWindow"
 +-width 34
 +-commandRepeatable 1
 +-mi "Assign" ("hyperShade -assign testMat;")
 +-mi "shade" ("setAttr \"testMat.transparency\" -type double3 0 0 0 ;")
 +-mi "30" ("setAttr \"testMat.transparency\" -type double3 0.3 0.3 0.3 ;")
 +-mi "50" ("setAttr \"testMat.transparency\" -type double3 0.5 0.5 0.5 ;")
 +-mi "70" ("setAttr \"testMat.transparency\" -type double3 0.7 0.7 0.7 ;")
 +-mi "line" ("setAttr \"testMat.transparency\" -type double3 1 1 1 ;")
 +-mi "create" ("shadingNode -n \"testMat\" -as lambert")
 +-st "iconOnly"
 +-imageOverlayLabel "T"
 +-image1 "render_lambert.xpm"
 +;
 +
 +// 
 +</code>
 +  * layout format <code javascript>
 +// row layout, side by side
 +rowColumnLayout -numberOfColumns 5;
 +  // buttons here
 +setParent ..;
 +
 +// grid layout, grid box like
 +gridLayout -numberOfColumns 3;
 +</code>
 +===== built-in UI manipulation =====
 +  * maya window title <code javascript>
 +// list all ui window
 +lsUI -windows; // list all window uis
 +
 +// query
 +window -q -title $gMainWindow
 +
 +// check exist and delete 
 +if (`window -ex outlinerPanel1Window`) deleteUI outlinerPanel1Window;else OutlinerWindow; // toggle outliner
 +
 +// change
 +$window=$gMainWindow
 +string $newT="Autodesk Maya 2009 x64 Unlimited: untitled | cool";
 +window -edit -title $newT $window;
 +// hide title bar (true no UI by: press ctrl+space; then run this cmd)
 +window -e -titleBar (!`window -q -titleBar $gMainWindow`) $gMainWindow;
 +</code>
 +  * get panel reference <code javascript>getPanel -visiblePanels;</code>
 +  * dialog <code javascript>confirmDialog -title "Confirm" -message "Are you sure?"
 +    -button "Yes" -button "No" -defaultButton "Yes"
 +    -cancelButton "No" -dismissString "No";</code>
 +  * prompt <code javascript>
 +string $text;
 +string $result = `promptDialog
 +        -title "Command Window"
 +        -message "Enter your cmd: (like ?)"
 +        -text "default answer here"
 +        -button "move" -button "rotate" -button "scale" -button "Cancel"
 +        -defaultButton "OK" -cancelButton "Cancel"
 +        -dismissString "Cancel"`;
 + 
 +if ($result == "move") {
 +        $text = `promptDialog -query -text`;
 +        eval("move -"+$text);
 +}
 +</code>
 +  * simple window gui<code javascript>string $windowName = "Maya_Weight_Tool";
 +if(`window -ex $windowName`) deleteUI $windowName;
 +window -t $windowName -rtf 1 -s 0 -mxb 0 -wh 180 250 -ip $windowName;
 +//resize-to-fit, res-izable, max button -interactivePlacement
 +// layout:gridLayout -numberOfColumns 3; columnLayout -adjustableColumn 1 ;
 +// add gui elements
 +</code>
 +  * float channel box<code javascript>
 +//ref: http://download.autodesk.com/us/maya/2010help/Commands/channelBox.html
 +window;
 +formLayout form;
 +channelBox dave;
 +formLayout -e
 +    -af dave "top" 0
 +    -af dave "left" 0
 +    -af dave "right" 0
 +    -af dave "bottom" 0
 +    form;
 +showWindow;
 +
 +// Color all attributes names, which have an attribute name
 +// beginning with "T", white (with a black background) for
 +// all current and future nodes.
 +// Then, color all attributes beginning with "A", which are
 +// contained in nodes that have their names beginning with "D", black.
 +
 +channelBox -attrRegex "T*" -attrColor 1.0 1.0 1.0 -attrBgColor 0.0 0.0 0.0 "cb1";
 +channelBox -e -nodeRegex "*" -attrRegex "A*" -attrColor 0 0 0 "cb1";
 +</code>
 +  * open project in Explore (windows, mac, linux detectable) <code javascript>
 +global proc shi_openProjectInExplorer()
 +{
 + // get the current project
 + string $projectRootPath = `workspace -q -rd`;
 + string $nativeProjectRootPath = toNativePath($projectRootPath);
 + string $systemCommand="";
 + if(`about -os` == "nt") $systemCommand = "explorer /e,"+$nativeProjectRootPath;
 + if(`about -os` == "linux64") $systemCommand = "konqueror "+$nativeProjectRootPath;
 + 
 + system ($systemCommand);
 + 
 +}
 +</code>
 +
 +===== QT Gui for Maya 2011 and above =====
 +
 +  * basic mel and QT gui design and interact: 
 +    * http://www.creativecrash.com/tutorials/maya-mel-qt-and-you-interfacing-with-the-qt-designer
 +  * more GUI elements interaction:
 +    * http://www.creativecrash.com/maya/tutorials/scripting/mel/c/using-qt-designer-for-mel-interfaces
 +  * Another QT in Maya design example
 +    * http://www.attackack.com/maya-tool-pg1
 +
 +  * QT ui and Maya mel ui
 +{{graphic:qt_ui.jpg?300 |}}
 +^ QT ^ MEL ^
 +|1-push Button (under Buttons group) | button |
 +|2-radio button (under Buttons group) | radioButton|
 +|3-check box(under Buttons group) | checkBox|
 +|4-combo box (under containers group) | optionMenu|
 +|5-line edit (under input widgets group) | textField|
 +|6-spin box (under input widgets group) |   |
 +|7-double spine box (under input widgets group)|  |
 +|8-dial (under input widgets group) | |
 +|9-list view (under item views model based) | textScrollList|
 +|10-horizontal slider (under input widgets) | intSlider|
 +|11-label (under display widgets group) | text |
 +|12-progress bar (under display widgets group) | progressBar|
 +|13-vertical slider (under input widgets) | intSlider|
 +|14-horizontal line (under input widgets) |  |
 +|15-vertical line (under input widgets) |  |
 +|16-group box (under containers group) |  |
 +|17-tab widget (under container group) | tabLayout|
 +|18-main window | window|
 +
 +  * other maya mel ui
 +    * scrollfield (like textArea)
 +  * make QT dockable <code mel>string $layout1=`paneLayout -cn "single" -p $gMainWindow`;
 +dockControl -aa "all" -a "right" -fl off -con $layout1 -l "MainWindow";
 +control -e -p $layout1 $dialog;</code>
 +
 +====== DIY Plugin related melscript======
 +
 +  * load and unload plugin <code>
 +loadPlugin "/user_data/ARCHIVE/dev/mayadev/pickExample.so";
 +unloadPlugin "/user_data/ARCHIVE/dev/mayadev/pickExample.so";
 +unloadPlugin hellow
 +hellow cool
 +hello "yes"
 +pickExample
 +</code>
 +
 +
 +====== Mel ScriptJob and ScriptNode ======
 +
 +I came across this when I was developing a rig system that requires how-condition-scripting and embeded script function for a on-server maya file.
 +
 +  * ScriptJob: run a maya mel function when "a condition happens" like attribute change or thing selected. (like a "EventListener")
 +  * ScriptNode: contains a piece of mel code inside a node called ScriptNode (accessible in Expression Editor); it runs when a "Maya Event happens", like file open/close, gui open/close.
 +
 +Short difference is:
 +  * ScriptJob is normally running through the your working time
 +  * ScriptNode is running at initialize or end stage.
 +
 +ScriptNode<----ScriptJob---->ScriptNode
 +
 +====== Math in 3D ======
 +
 +  * get camera to target (object to object direction)<code javascript>
 +//Get camera's position:
 +vector $camPos = `camera -query -position $cameraName`;
 +//Get camera's target's position:
 +vector $camTarget = `camera -query -worldCenterOfInterest $cameraName`;
 +
 +//Calculate direction:
 +vector $cameraDir = $camTarget - $camPos;
 +//Normalize direction:
 +vector $normalizedDir = unit ($cameraDir);
 +
 +print ("Direction: " + $normalizedDir);
 +</code>
 +
 +  * vector2rot <code javascript>
 +// script for converting vector into worldspace rotations.
 +
 +// adrian@kolektiv.com Jun 20/04
 +// AWGUA Maya Seminar August 2004
 +
 +// Description: An essential script for converting velocity and up vectors into
 +// Euler rotations.
 +// NOTE: If you're using this for particle instancing, make sure to convert rotational
 +// values in degrees to radians *twice*, due to a little legacy bug. Like this:
 +// vector $direction = worldVelocity;
 +// vector $up = normalPP;
 +// float $rot[] = `vector2rot $direction $up`;
 +// float $rotX = deg_to_rad( deg_to_rad( $rot[0] ) );
 +// float $rotY = deg_to_rad( deg_to_rad( $rot[1] ) );
 +// float $rotZ = deg_to_rad( deg_to_rad( $rot[2] ) );
 +
 +// Special thanks goes out to Steve Hwan for providing the guts, I just Maya-nized it.
 +
 +////
 +// main proc
 +global proc float[] vector2rot( vector $direction, vector $up ) {
 +
 +// normalize vectors first
 +$direction = unit( $direction );
 +$up = unit( $up );
 +
 +// calculate the side vector
 +vector $sideVec = cross( $up, $direction );
 +vector $upVec = cross( $direction, $sideVec );
 +
 +float $cosY = sqrt( ($sideVec.x)*($sideVec.x) + ($sideVec.y)*($sideVec.y) );
 +
 +// solve each angle
 +float $rotZ = atan2( ($sideVec.y), ($sideVec.x) );
 +float $rotY = atan2( -($sideVec.z), ( (($sideVec.x)+($sideVec.y)) / (cos( $rotZ ) + sin( $rotZ ) ) ) );
 +float $rotX = atan2( ($upVec.z), ($direction.z) );
 +
 +// convert to degrees
 +$rotX = rad_to_deg( $rotX );
 +$rotY = rad_to_deg( $rotY );
 +$rotZ = rad_to_deg( $rotZ );
 +
 +// return x,y,z rotations
 +return { $rotX, $rotY, $rotZ };
 +
 +} // vector2rot
 +</code>
 +
 +
 +
 +====== Common mel function lib ======
 +===== display func=====
 +  * outliner show<code javascript>
 +// toggle show hide of outliner
 +global proc tOutliner()
 +{
 +if ( `window -exists outlinerPanel1Window` )
 +deleteUI -window outlinerPanel1Window;
 +else
 +tearOffPanel "Outliner" "outlinerPanel" false;
 +}
 +</code>
 +  * toggle wireframe<code javascript>
 +// toggle wireOnShade of cursor below window
 +global proc tWireOnShade()
 +{
 +global int $g_tWireOnShade=0;
 +
 +if ($g_tWireOnShade != 1){
 + setWireframeOnShadedOption 1 `getPanel -underPointer`;
 + $g_tWireOnShade = 1;
 + }
 +else{
 + setWireframeOnShadedOption 0 `getPanel -underPointer`;
 + $g_tWireOnShade = 0;
 + }
 +}
 +</code>
 +===== general edit=====
 +  * rename selected prompt<code javascript>
 +global proc gxRename()
 +{
 +string $text;
 +
 +string $result = `promptDialog 
 + -title "Super Rename Window"
 + -message "Enter new Name:"
 + -button "OK" -button "Cancel"
 + -defaultButton "OK" -cancelButton "Cancel"
 + -dismissString "Cancel"`;
 +
 +if ($result == "OK") {
 +
 + // query the entry typed by the user
 + $text = `promptDialog -query -text`;
 + string $selected[] = `ls -sl`;
 + rename $selected[0] $text;
 + //print("HELLO to "+ $text +"\n");
 +}   
 +else {
 + //print("fine. I won't say hello then :(\n");
 +}
 +}
 +</code>
 +  * move 2nd selected object to 1st selected object<code javascript>
 +global proc gxMove2()
 +{
 +string $attributeList[] = {"tx", "ty", "tz", "rx", "ry", "rz", "sx", "sy", "sz"};
 +string $sel[] = `ls -sl`;
 +string $attribute;
 +for($attribute in $attributeList) {
 +setAttr ($sel[1] + "." + $attribute) `getAttr ($sel[0] + "." + $attribute)`;
 +}
 +}
 +</code>
 +  * create a layer from selected<code javascript>
 +global proc gxNewObjLayer()
 +{
 +// create a layer from selected object and use first object's name + "Lyr" as layer name
 +to be added later
 +}
 +</code>
 +  * manual tune a channel value<code javascript>
 +global proc gxTune(string $ch,float $val){
 +string $selected[] = `ls -sl`;
 +float $old=`getAttr ($selected[0]+"."+$ch)`;
 +setAttr ($selected[0]+"."+$ch) ($old+$val);
 +}
 +button -l "+001" -c "gxTune(\"ry\",0.001)";
 +button -l "-001" -c "gxTune(\"ry\",-0.001)";
 +button -l "-002" -c "gxTune(\"ry\",-0.002)";
 +</code>
 +===== select func=====
 +  * set face-edge-point select mode<code javascript>
 +global proc tSelectMode(int $curMode)
 +{
 +global int $g_tSelectMode=0;
 +
 +if ($g_tSelectMode != $curMode){
 + if ($curMode == 1) {SelectVertexMask;}
 + if ($curMode == 2) {SelectEdgeMask;}
 + if ($curMode == 3) {SelectFacetMask;}
 + if ($curMode == 0) {SelectToggleMode;}
 + $g_tSelectMode = $curMode;
 + }
 +else{
 + SelectToggleMode;
 + $g_tSelectMode = 0;
 + }
 +}
 +</code>
 +
 +====== Rigging related function ======
 +===== Mesh-Joint weight map store and restore =====
 + 
 +<code javascript>
 +// vtx
 +$selVtx=`ls -sl -fl`;
 +$countVtx=size($selVtx);
 +print ("vtx :"+$countVtx);
 +// bones
 +string $selJnt[]=`ls -sl`;
 +$countJnt=size($selJnt);
 +print ("jnt :"+$countJnt);
 +print $selJnt;
 +// matrix
 +string $declare = ( "matrix $wmap[" + $countJnt + "][" + $countVtx + "];" );
 +eval $declare;
 +// joint based store data
 +for ( $i = 0; $i < $countJnt ; $i++ ) {
 +    print ("now storing $selJnt["+$i+"] : "+$selJnt[$i]+"\n");
 +
 +    for ( $j = 0; $j < $countVtx ; $j++ ) {
 +        $tmpW=`skinPercent -t $selJnt[$i] -q skinCluster1 $selVtx[$j]`;
 +        string $declare = ( "$wmap[" + $i + "][" + $j + "]="+$tmpW+";" );
 +        eval $declare;
 +    }
 +    print ("Finished storing $selJnt["+$i+"] : "+$selJnt[$i]+"\n");
 +}
 +
 +// test query
 +skinPercent -t $selJnt[0] -q skinCluster1 $selVtx[0];
 +print $wmap[0][0];
 +// apply weight, name the targe joint as jointName+"new"
 +// skinPercent -tv joint1 0.2 skinCluster1 pPlane1.cv[100];
 +
 +// vtx base re-assign
 +float $tmpWt;
 +$countJnt1=$countJnt-1;
 +// vtx base re-assign, manual turn off all the holding
 +for ( $i = 0; $i < $countJnt1 ; $i++ ){
 +    print ("now apply for $selJnt["+$i+"] : "+$selJnt[$i]+"\n");
 +    $newJnt=($selJnt[$i]+"new"); // new jnt naming convention
 +    for ( $j = 0; $j < $countVtx ; $j++ ) {
 +        string $declare = ( "$tmpWt=$wmap[" + $i + "][" + $j + "];" );
 +        eval $declare;
 +        skinPercent -tv $newJnt $tmpWt skinCluster1 $selVtx[$j];
 +    }
 +    print ("Finished for $selJnt["+$i+"] : "+$selJnt[$i]+"\n");
 +    // hold it
 +    setAttr ($newJnt+".liw" 1;
 +}
 +print $wmap;
 +// test query
 +skinPercent -t $selJnt[0] -q skinCluster1 $selVtx[0];
 +</code>
 +====== OS-System related function ======
 +
 +===== open project folder in OS File Manager =====
 +
 +<code javascript>
 +// expanded based on http://oy-maya-scripts.googlecode.com
 +global proc shi_openProjectInExplorer()
 +{
 +// get the current project
 +string $projectRootPath = `workspace -q -rd`;
 +string $nativeProjectRootPath = toNativePath($projectRootPath);
 +string $systemCommand="";
 +if(`about -os` == "nt") string $systemCommand = "explorer /e,"+$nativeProjectRootPath;
 +if(`about -os` == "linux64") string $systemCommand = "konqueror "+$nativeProjectRootPath;
 +
 +system ($systemCommand);
 +}
 +</code>
 +  * for os detection in python <code python>
 +import os
 +if os.name == 'nt' :
 +    maya = 'maya.exe'
 +else :
 +    maya = 'maya.bin'
 +</code>
 +  * get mel proc file and the arguments <code javascript>
 +global proc printMelArgs(string $procedure)
 +{
 +string $scriptFile = `whatIs $procedure`;
 +int $fileId = 0;
 +$scriptFile = substitute(".* found in: ", $scriptFile, "");
 +$fileId = fopen($scriptFile, "r");
 +print("Found " + $procedure + " in file " + $scriptFile + ".\n");
 +
 +if($fileId)
 +{
 +  while(!feof($fileId))
 +  {
 +    $currentLine = fgetline($fileId);
 +    if(`match (".*proc.*" + $procedure) $currentLine` != "")
 +    print ($currentLine);
 +  }
 +  fclose $fileId;
 +}
 +}
 +</code>
 +====== Custom UI creation function ======
 +===== custom menu creation =====
 +<code javascript>
 +global proc myMenu()
 +{
 +global string $showMyMenuCtrl;
 +if (`menu -exists $showMyMenuCtrl`)
 +   deleteUI $showMyMenuCtrl;
 +string $name = "My Menu";
 +global string $gMainWindow;
 +$showMyMenuCtrl = `menu -p $gMainWindow -to true -l $name`;
 +menuItem -p $showMyMenuCtrl -l "Alpha" -c ("source \"alpha.mel\"; ");
 +menuItem -p $showMyMenuCtrl -l "Bravo" -c ("source \"bravo.mel\"; ");
 +menuItem -p $showMyMenuCtrl -l "Charlie" -c ("source \"charlie.mel\"; ");
 +};
 +myMenu;
 +</code>
 +===== Custom HUD creation =====
 +  * read this guide from Maya Help file: [[http://download.autodesk.com/us/maya/2009help/index.html?url=PC_Create_a_custom_headsup_display_readout.htm,topicNumber=d0e82090|link]]
 +
 +
 +
 +====== GUI mel for my own use ======
 +
 +^ toolbox | shiShelfTool |  |
 +^ markingmenu | mm_Sel_filter |
 +^ menu | vip_item_menu |
 +
 +===== shiShelfTool =====
 +
 +A floating shelf with built-in functions and Realtime Strategy Game like Commanding icons.
 +
 +
 +===== mm_shi_sel_filter =====
 +
 +<code javascript mm_shi_sel_filter.mel>
 +    menuItem
 +        -label "shiSelectPoly" 
 +        -command "setObjectPickMask \"All\" 0;selectType -polymesh 1;\n" 
 +        -radialPosition "N" 
 +        menuEditorMenuItem2;
 +
 +    menuItem
 +        -label "shiSelectLocator" 
 +        -command "setObjectPickMask \"All\" 0;selectType -locator 1\n" 
 +        -radialPosition "NE" 
 +        menuEditorMenuItem8;
 +
 +    menuItem
 +        -label "shiSelectCluster" 
 +        -command "setObjectPickMask \"All\" 0;selectType -cluster 1;\n" 
 +        -radialPosition "E" 
 +        menuEditorMenuItem4;
 +
 +    menuItem
 +        -label "shiSelectLattice" 
 +        -command "setObjectPickMask \"All\" 0;selectType -lattice 1;\n" 
 +        -radialPosition "SE" 
 +        menuEditorMenuItem6;
 +
 +    menuItem
 +        -label "shiSelectCurve" 
 +        -command "setObjectPickMask \"All\" 0;setObjectPickMask \"Curve\" 1;\n" 
 +        -radialPosition "S" 
 +        menuEditorMenuItem3;
 +
 +    menuItem
 +        -label "shiSelectIK" 
 +        -command "setObjectPickMask \"All\" 0;selectType -ikHandle 1;\n" 
 +        -radialPosition "SW" 
 +        menuEditorMenuItem7;
 +
 +    menuItem
 +        -label "shiSelectJoint" 
 +        -command "setObjectPickMask \"All\" 0;setObjectPickMask \"Joint\" true;\n" 
 +        -radialPosition "W" 
 +        -enableCommandRepeat 1
 +        menuEditorMenuItem5;
 +
 +    menuItem
 +        -label "shiSelectDeformer" 
 +        -command "setObjectPickMask \"All\" 0;setObjectPickMask \"Deformer\" true;\n" 
 +        -radialPosition "NW" 
 +        menuEditorMenuItem9;
 +
 +    menuItem
 +        -label "shiSelectLight" 
 +        -command "setObjectPickMask \"All\" 0;selectType -light 1;\n" 
 +        menuEditorMenuItem10;
 +
 +    menuItem
 +        -label "shiSelectCam" 
 +        -command "setObjectPickMask \"All\" 0;selectType -camera 1;\n" 
 +        menuEditorMenuItem11;
 +
 +    menuItem
 +        -divider 1
 +        menuEditorMenuItem12;
 +
 +    menuItem
 +        -label "shiSelectMaskAll" 
 +        -command "setObjectPickMask \"All\" 1;\n" 
 +        menuEditorMenuItem13;
 +
 +    menuItem
 +        -label "shiLockSelection" 
 +        -command "updateLockSelectionIcon;" 
 +        menuEditorMenuItem14;
 +
 +setParent -m ..;
 +</code>
 +====== scripts for my own use ======
 +
 +^ material |color_bucket_gen |mm_paint_list |
 +^ modeling |common_create |cube_softify |
 +
 +===== ref creation ===== 
 +<code javscript>
 +// ref: http://xyz2.net/mel/mel.103.htm
 +// usage: it create refPlane01, and refMat01, and load ref01.png under ref/ folder
 +// refPlane
 +polyPlane -ax 0 0 1 -w 10 -h 10 -sx 2 -sy 2 -n "refPlane01";
 +move -a 0 0 -5;
 +//refMat;
 +string $myRefMat = `shadingNode -asShader lambert -name "refMat01"`;
 +string $mySG = `sets -renderable true -noSurfaceShader true -empty -name "refMatSG01"`;
 +connectAttr -f ( $myRefMat + ".outColor" ) ( $mySG + ".surfaceShader" );
 +string $myFileNode = `shadingNode -asTexture file -name "refFile01"`;
 +connectAttr -f ( $myFileNode + ".outColor" ) ( $myRefMat + ".color" );
 +string $filepath = "ref/ref01.png";
 +setAttr -type "string" ( $myFileNode + ".fileTextureName" ) $filepath;
 +select refPlane01;
 +hyperShade -assign refMat01;
 +/* // link map png transparency
 +connectAttr -force refFile01.outTransparency refMat01.transparency;
 +*/
 +</code>
 +===== color bucket button set (Setup+UI) =====
 + <code javascript>// color bucket - create preset materials
 +// (red,blue,green,grey,white,black,yellow)
 +/*
 +color bucket
 +*/
 +global proc ccMatSetup()
 +{
 +string $myNewColor = `shadingNode -asShader lambert -name "ccRed"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 1 0 0;
 +string $myNewColor = `shadingNode -asShader lambert -name "ccGreen"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 0 1 0;
 +string $myNewColor = `shadingNode -asShader lambert -name "ccBlue"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 0 0 1;
 +string $myNewColor = `shadingNode -asShader lambert -name "ccWhite"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 1 1 1;
 +string $myNewColor = `shadingNode -asShader lambert -name "ccGrey"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 0.5 0.5 0.5;
 +string $myNewColor = `shadingNode -asShader lambert -name "ccBlack"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 0 0 0;
 +string $myNewColor = `shadingNode -asShader lambert -name "ccYellow"`;
 +setAttr -type double3 ( $myNewColor + ".color" ) 1 1 0;
 +}
 +/* please put this shelf button in your fav UI
 +shelfButton
 +-label "ccMat" 
 +-imageOverlayLabel "ccMat" 
 +-image "render_rampShader.xpm" 
 +-image1 "render_rampShader.xpm"
 +-style "iconOnly" 
 +-command "HypershadeWindow" 
 +-mi "ccRed" ("hyperShade -assign ccRed;")
 +-mi "ccGreen" ("hyperShade -assign ccGreen;")
 +-mi "ccBlue" ("hyperShade -assign ccBlue;")
 +-mi "ccWhite" ("hyperShade -assign ccWhite;")
 +-mi "ccGrey" ("hyperShade -assign ccGrey;")
 +-mi "ccBlack" ("hyperShade -assign ccBlack;")
 +-mi "ccYellow" ("hyperShade -assign ccYellow;")
 +-mi "-----------" ("")
 +-mi "-----------" ("")
 +-mi "ccMatSetup" ("ccMatSetup")
 +-sourceType "mel" 
 +-commandRepeatable 1
 +;
 +*/
 +</code>
 +<code javascript mm_shi_cc_assign.mel>
 +/* setup guide - total manual way in hotkey editor
 +// yourMM_press
 +if (`popupMenu -exists tempMM`) { deleteUI tempMM; }
 +popupMenu -button 1 -ctl false -alt false -allowOptionBoxes true -parent viewPanes -mm 1 tempMM;
 +source "mm_shi_cc_assign.mel"; // only to change this
 +// yourMM_release
 +if (`popupMenu -exists tempMM`) { deleteUI tempMM; }
 +*/
 +    menuItem -label "ccRed" -command "hyperShade -assign ccRed;" mmCCAmi_red;
 +    menuItem -label "ccGreen" -command "hyperShade -assign ccGreen;" mmCCAmi_green;
 +    menuItem -label "ccBlue" -command "hyperShade -assign ccBlue;" mmCCAmi_blue;
 +    menuItem -label "ccWhite" -command "hyperShade -assign ccWhite;" mmCCAmi_white;
 +    menuItem -label "ccGrey" -command "hyperShade -assign ccGrey;" mmCCAmi_grey;
 +    menuItem -label "ccBlack" -command "hyperShade -assign ccBlack;" mmCCAmi_black;
 +    menuItem -label "ccYellow" -command "hyperShade -assign ccYellow;" mmCCAmi_yellow;
 +    menuItem -label "---------" -command "" mmCCAmi_dash;
 +    menuItem -label "ccMatSetup" -command "ccMatSetup" mmCCAmi_ccMatSetup;
 +setParent -m ..;
 +</code>
 +
 +===== Play with Cube =====
 +<code javascript>
 +// title: random cube generator v0.1a
 +// usage: create random shaped cube
 +for($i=0;$i<10;$i++){
 +int $tmpVary=6;
 +int $tmpSize=10;
 +polyCube -w $tmpSize -h $tmpSize -d $tmpSize -cuv 4;
 +string $selected[]=`ls -sl`;
 +$tmpCube=$selected[0];
 +//move -5 -5 -5 ($tmpCube+".scalePivot") ($tmpCube+".rotatePivot") ;
 +move (50) (0+15*$i) 0;
 +
 +$tmpP1=floor(rand(0,2));
 +$tmpP2=floor(rand(3,5));
 +$tmpP3=floor(rand(6,7));
 +select -r $tmpCube.vtx[$tmpP1] ;
 +move -r (rand($tmpVary)) (rand($tmpVary)) (rand($tmpVary));
 +select -r $tmpCube.vtx[$tmpP2] ;
 +move -r (rand($tmpVary)) (rand($tmpVary)) (rand($tmpVary));
 +select -r $tmpCube.vtx[$tmpP3] ;
 +move -r (rand($tmpVary)) (rand($tmpVary)) (rand($tmpVary));
 +}
 +select -cl;
 +</code>
 +
 +<code javascript>
 +// selected cubic soft edge script - v0.1
 +// shining 2011 mar
 +// able to handle multi cube selection, no cube as tmpCube
 +
 +string $selected[] = `ls -sl`;
 +
 +for ($selectedItem in $selected) { //loop 1 starts
 +rename $selectedItem "tmpCube" ;
 +// find rough size
 +$tmpSizeValue=`polyEvaluate -boundingBox tmpCube`;
 +float $tmpSizeValueX = ($tmpSizeValue[1]-$tmpSizeValue[0]);
 +float $tmpSizeValueY = ($tmpSizeValue[3]-$tmpSizeValue[2]);
 +float $tmpSizeValueZ = ($tmpSizeValue[5]-$tmpSizeValue[4]);
 +float $tmpCubeValue=0.1*min($tmpSizeValueX,min($tmpSizeValueY,$tmpSizeValueZ));
 +// scale in cube
 +move -r 0 ($tmpCubeValue) 0 tmpCube.vtx[0:1] tmpCube.vtx[6:7];
 +move -r 0 (-1*$tmpCubeValue) 0 tmpCube.vtx[2:5];
 +move -r 0 0 (-1*$tmpCubeValue) tmpCube.vtx[0:3];
 +move -r 0 0 ($tmpCubeValue) tmpCube.vtx[4:7];
 +move -r (-1*$tmpCubeValue) 0 0 tmpCube.vtx[1] tmpCube.vtx[3] tmpCube.vtx[5] tmpCube.vtx[7];
 +move -r ($tmpCubeValue) 0 0 tmpCube.vtx[0] tmpCube.vtx[2] tmpCube.vtx[4] tmpCube.vtx[6];
 +// extrube back cube
 +polyExtrudeFacet -constructionHistory 1 -keepFacesTogether 1 -divisions 1 -twist 0 -taper 1 -off 0 -lt 0 0 ($tmpCubeValue) -smoothingAngle 30 tmpCube.f[0] tmpCube.f[2];
 +polyExtrudeFacet -constructionHistory 1 -keepFacesTogether 1 -divisions 1 -twist 0 -taper 1 -off 0 -lt 0 0 ($tmpCubeValue) -smoothingAngle 30 tmpCube.f[4] tmpCube.f[5] tmpCube.f[7] tmpCube.f[9] tmpCube.f[11] tmpCube.f[13];
 +polyExtrudeFacet -constructionHistory 1 -keepFacesTogether 1 -divisions 1 -twist 0 -taper 1 -off 0 -lt 0 0 ($tmpCubeValue) -smoothingAngle 30 tmpCube.f[1] tmpCube.f[3] tmpCube.f[6] tmpCube.f[8] tmpCube.f[10] tmpCube.f[12] tmpCube.f[14:16] tmpCube.f[18:19] tmpCube.f[21:24] tmpCube.f[26:27] tmpCube.f[29];
 +polySmooth  -mth 0 -dv 1 -c 1 -kb 1 -ksb 1 -khe 0 -kt 1 -kmb 1 -suv 1 -peh 0 -sl 1 -dpe 1 -ps 0.1 -ro 1 -ch 1 tmpCube;
 +polyDelEdge -cv true -ch 1 tmpCube.e[216:240] tmpCube.e[242] tmpCube.e[244] tmpCube.e[246] tmpCube.e[248] tmpCube.e[250] tmpCube.e[252] tmpCube.e[254] tmpCube.e[256] tmpCube.e[258] tmpCube.e[260] tmpCube.e[262] tmpCube.e[264] tmpCube.e[266] tmpCube.e[268] tmpCube.e[270] tmpCube.e[272] tmpCube.e[274] tmpCube.e[276] tmpCube.e[278] tmpCube.e[284] tmpCube.e[286] tmpCube.e[296] tmpCube.e[298] tmpCube.e[304] tmpCube.e[306] tmpCube.e[308] tmpCube.e[310] tmpCube.e[316] tmpCube.e[318] tmpCube.e[328] tmpCube.e[330] tmpCube.e[336] tmpCube.e[338] tmpCube.e[340] tmpCube.e[342] tmpCube.e[344] tmpCube.e[346] tmpCube.e[364] tmpCube.e[366] tmpCube.e[384] tmpCube.e[386] tmpCube.e[388] tmpCube.e[390] tmpCube.e[392] tmpCube.e[394] tmpCube.e[412] tmpCube.e[414];
 +rename tmpCube $selectedItem ;
 +
 +//loop 1 ends
 +</code>
 +
 +
 +====== Portable hotkey ======
 +
 +Mel hotkey initialize sequence
 +  - userRunTimeCommands.mel (defining **a mel script** into alisa name)
 +  - userNamedCommands.mel (give a link name to each alias command)
 +  - userHotkeys.mel (assign keystroke to each link)
 +
 +** Runtime command vs Name command**
 +  * runtime command is more like "alias" in bash or "doskey" in dos, simply a one word short command for a multi-line commands
 +    * if you use functions most, then you can ignore the alias
 +  * runtime command is used for hokey editor registration,
 +  * name command is more and enough for working with hotkey assigning, if you call from hotkey, you need a name command
 +===== Example of NameCommand-only way of shortcut =====
 +require "shi_fun.mel" load first for my personal cmds;
 +<code javascript>
 +//-----------------------modeling
 +nameCommand -ann "NC_shiToggleMode_1" -c ("shiToggleMode(1)") NC_shiToggleMode_1;
 +hotkey -k "1" -ctl -n ("NC_shiToggleMode_1");
 + 
 +nameCommand -ann "NC_shiToggleMode_2" -c ("shiToggleMode(2)") NC_shiToggleMode_2;
 +hotkey -k "2" -ctl -n ("NC_shiToggleMode_2");
 + 
 +nameCommand -ann "NC_shiToggleMode_3" -c ("shiToggleMode(3)") NC_shiToggleMode_3;
 +hotkey -k "3" -ctl -n ("NC_shiToggleMode_3");
 + 
 +//------------------------ view port
 +nameCommand -ann "NC_view_tWireframe" -c ("shiToggleWireOnShade") NC_view_tWireframe;
 +hotkey -k "f" -ctl -alt -n ("NC_view_tWireframe");
 + 
 +//------------------------ windows
 + 
 +// outliner
 +nameCommand -ann "NC_win_outliner" -c ("if (`window -ex outlinerPanel1Window`) deleteUI outlinerPanel1Window;else OutlinerWindow;") NC_win_outliner;
 +hotkey -k "4" -ctl -n ("NC_win_outliner");
 + 
 +// script editor
 +nameCommand -ann "NC_win_scriptEditor" -c ("if (`window -ex scriptEditorPanel1Window`) deleteUI scriptEditorPanel1Window;else ScriptEditor;") NC_win_scriptEditor;
 +hotkey -k "x" -ctl -alt -n ("NC_win_scriptEditor");
 + 
 +// hyperShade
 +nameCommand -ann "NC_win_hyperShade" -c ("if (`window -ex hyperShadePanel1Window`) deleteUI hyperShadePanel1Window;else HypershadeWindow") NC_win_hyperShade;
 +hotkey -k "s" -ctl -alt -n ("NC_win_hyperShade");
 + 
 +// graph editor
 +nameCommand -ann "NC_win_graphEditor" -c ("if (`window -ex graphEditor1Window`) deleteUI graphEditor1Window;else GraphEditor") NC_win_graphEditor;
 +hotkey -k "g" -ctl -alt -n ("NC_win_graphEditor");
 + 
 +//------------------------ redo
 +nameCommand -ann "NC_fun01" -c ("fun01") NC_fun01;
 +hotkey -k "d" -ctl -alt -n ("NC_fun01");
 +</code>
 +
 +
 +
 +===== Example of RunTimeCommand NameCommand way of shortcut =====
 +
 +require "shi_fun.mel" load first for my personal cmds;
 +===== runtime cmd =====
 +<code javascript>
 +//Maya Preference 2010 (Release 1)
 +//
 +//
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`;\nfloat $horizontalFilmOffset = `getAttr ($camera + \".horizontalFilmOffset\")`;\nsetAttr ($camera + \".horizontalFilmOffset\" ($horizontalFilmOffset + 0.02) ;\nprint ($camera +\".horizontalFilmOffset = \" + ($horizontalFilmOffset + 0.02)  + \"\\n\"); ")
 + camRight;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`;\nfloat $horizontalFilmOffset = `getAttr ($camera + \".horizontalFilmOffset\")`;\nsetAttr ($camera + \".horizontalFilmOffset\" ($horizontalFilmOffset - 0.02) ;\nprint ($camera +\".horizontalFilmOffset = \" + ($horizontalFilmOffset - 0.02)  + \"\\n\"); ")
 + camLeft;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`;\nfloat $verticalFilmOffset = `getAttr ($camera + \".verticalFilmOffset\")`;\nsetAttr  ($camera+ \".verticalFilmOffset\" ($verticalFilmOffset + 0.02) ;\nprint ($camera + \".verticalFilmOffset = \" +($verticalFilmOffset + 0.02 ) + \"\\n\"); ")
 + camUp;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`;\nfloat $verticalFilmOffset = `getAttr ($camera + \".verticalFilmOffset\")`;\nsetAttr  ($camera+ \".verticalFilmOffset\" ($verticalFilmOffset - 0.02) ;\nprint ($camera + \".verticalFilmOffset = \" +($verticalFilmOffset - 0.02) + \"\\n\"); ")
 + camDown;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`;\nsetAttr  ($camera + \".verticalFilmOffset\") 0.0;\nsetAttr  ($camera +\".horizontalFilmOffset\") 0.0;\nsetAttr  ($camera + \".overscan\" 1.0 ; ")
 + camHome;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`; float $overscan =\n`getAttr ($camera + \".overscan\")`; setAttr  ($camera + \".overscan\")\n($overscan - 0.1) ; print ($camera + \".overscan = \" + ($overscan - 0.1)  +\n\"\\n\");\n")
 + camIn;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("string $currentPanel = `getPanel -up`;\nstring $camera = `modelPanel -q -camera $currentPanel`; float $overscan =\n`getAttr ($camera + \".overscan\")`; setAttr  ($camera + \".overscan\")\n($overscan + 0.1) ; print ($camera + \".overscan = \" + ($overscan + 0.1)  +\n\"\\n\"); ")
 + camOut;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("shiRename")
 + shiRenameCmd;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("srcTool")
 + myToolWindow;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("GraphEditor")
 + winGraphEditor;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("HotkeyPreferencesWindow;")
 + winHotkeyEditor;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("HypershadeWindow;")
 + winHyperShade;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("shiToggleWireOnShade")
 + act_toggle_wire_on_shade;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("OutlinerWindow;")
 + winOutliner;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("ScriptEditor;")
 + winScriptEditor;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("srcShelf")
 + win_shiShelfTool;
 +
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("dnMePan")
 + cam_PanTool;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("OutlinerWindow")
 + win_outliner;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("shiToggleMode(1)")
 + fun_shiToggleMode_1;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("shiToggleMode(2)")
 + fun_shiToggleMode_2;
 +
 +runTimeCommand
 + -annotation ""
 + -category "User"
 + -commandLanguage "mel"
 + -command ("shiToggleMode(3)")
 + fun_shiToggleMode_3;
 +</code>
 +
 +===== name cmd =====
 +<code javascript>
 +//Maya Preference 2010 (Release 1)
 +//
 +//
 +
 +nameCommand
 + -annotation "camRightNameCommand"
 + -sourceType "mel"
 + -command ("camRight")
 + camRightNameCommand;
 +
 +nameCommand
 + -annotation "camLeftNameCommand"
 + -sourceType "mel"
 + -command ("camLeft")
 + camLeftNameCommand;
 +
 +nameCommand
 + -annotation "camUpNameCommand"
 + -sourceType "mel"
 + -command ("camUp")
 + camUpNameCommand;
 +
 +nameCommand
 + -annotation "camDownNameCommand"
 + -sourceType "mel"
 + -command ("camDown")
 + camDownNameCommand;
 +
 +nameCommand
 + -annotation "camHomeNameCommand"
 + -sourceType "mel"
 + -command ("camHome")
 + camHomeNameCommand;
 +
 +nameCommand
 + -annotation "camInNameCommand"
 + -sourceType "mel"
 + -command ("camIn")
 + camInNameCommand;
 +
 +nameCommand
 + -annotation "camOutNameCommand"
 + -sourceType "mel"
 + -command ("camOut")
 + camOutNameCommand;
 +
 +nameCommand
 + -annotation "shiRenameCmdNameCommand"
 + -sourceType "mel"
 + -command ("shiRenameCmd")
 + shiRenameCmdNameCommand;
 +
 +nameCommand
 + -annotation "myToolWindowNameCommand"
 + -sourceType "mel"
 + -command ("myToolWindow")
 + myToolWindowNameCommand;
 +
 +nameCommand
 + -annotation "winGraphEditorNameCommand"
 + -sourceType "mel"
 + -command ("winGraphEditor")
 + winGraphEditorNameCommand;
 +
 +nameCommand
 + -annotation "winHotkeyEditorNameCommand"
 + -sourceType "mel"
 + -command ("winHotkeyEditor")
 + winHotkeyEditorNameCommand;
 +
 +nameCommand
 + -annotation "winHyperShadeNameCommand"
 + -sourceType "mel"
 + -command ("winHyperShade")
 + winHyperShadeNameCommand;
 +
 +nameCommand
 + -annotation "act_toggle_wire_on_shadeNameCommand"
 + -sourceType "mel"
 + -command ("act_toggle_wire_on_shade")
 + act_toggle_wire_on_shadeNameCommand;
 +
 +nameCommand
 + -annotation "winOutlinerNameCommand"
 + -sourceType "mel"
 + -command ("winOutliner")
 + winOutlinerNameCommand;
 +
 +nameCommand
 + -annotation "winScriptEditorNameCommand"
 + -sourceType "mel"
 + -command ("winScriptEditor")
 + winScriptEditorNameCommand;
 +
 +
 +nameCommand
 + -annotation "win_shiShelfToolNameCommand"
 + -sourceType "mel"
 + -command ("win_shiShelfTool")
 + win_shiShelfToolNameCommand;
 +
 +
 +nameCommand
 + -annotation "cam_PanToolNameCommand"
 + -sourceType "mel"
 + -command ("cam_PanTool")
 + cam_PanToolNameCommand;
 +
 +nameCommand
 + -annotation "win_outlinerNameCommand"
 + -sourceType "mel"
 + -command ("win_outliner")
 + win_outlinerNameCommand;
 +
 +nameCommand
 + -annotation "fun_shiToggleMode_1NameCommand"
 + -sourceType "mel"
 + -command ("fun_shiToggleMode_1")
 + fun_shiToggleMode_1NameCommand;
 +
 +nameCommand
 + -annotation "fun_shiToggleMode_2NameCommand"
 + -sourceType "mel"
 + -command ("fun_shiToggleMode_2")
 + fun_shiToggleMode_2NameCommand;
 +
 +nameCommand
 + -annotation "fun_shiToggleMode_3NameCommand"
 + -sourceType "mel"
 + -command ("fun_shiToggleMode_3")
 + fun_shiToggleMode_3NameCommand;
 +</code>
 +
 +===== hotkey binding =====
 +<code javascript>
 +//Maya Preference 2010 (Release 1)
 +//
 +//
 +hotkey -keyShortcut "e" -ctl -name ("cam_PanToolNameCommand");
 +
 +hotkey -keyShortcut "4" -ctl -name ("win_outlinerNameCommand");
 +hotkey -keyShortcut "1" -ctl -name ("fun_shiToggleMode_1NameCommand");
 +hotkey -keyShortcut "2" -ctl -name ("fun_shiToggleMode_2NameCommand");
 +hotkey -keyShortcut "3" -ctl -name ("fun_shiToggleMode_3NameCommand");
 +
 +hotkey -keyShortcut "Right" -ctl -name ("camRightNameCommand");
 +hotkey -keyShortcut "Left" -ctl -name ("camLeftNameCommand");
 +hotkey -keyShortcut "Up" -ctl -name ("camUpNameCommand");
 +hotkey -keyShortcut "Down" -ctl -name ("camDownNameCommand");
 +hotkey -keyShortcut "Home" -name ("camHomeNameCommand");
 +hotkey -keyShortcut "Page_Up" -name ("camInNameCommand");
 +hotkey -keyShortcut "Page_Down" -name ("camOutNameCommand");
 +
 +hotkey -keyShortcut "r" -ctl -name ("shiRenameCmdNameCommand");
 +
 +hotkey -keyShortcut "w" -ctl -alt -name ("myToolWindowNameCommand");
 +hotkey -keyShortcut "r" -ctl -alt -name ("win_shiShelfToolNameCommand");
 +
 +hotkey -keyShortcut "g" -ctl -alt -name ("winGraphEditorNameCommand");
 +hotkey -keyShortcut "h" -ctl -alt -name ("winHotkeyEditorNameCommand");
 +hotkey -keyShortcut "s" -ctl -alt -name ("winHyperShadeNameCommand");
 +hotkey -keyShortcut "x" -ctl -alt -name ("winHotkeyEditorNameCommand");
 +hotkey -keyShortcut "a" -ctl -alt -name ("winScriptEditorNameCommand");
 +
 +hotkey -keyShortcut "f" -ctl -alt -name ("act_toggle_wire_on_shadeNameCommand");
 +</code>
 +
 +