/* This file downloaded from Highend3d.com '' '' Highend3d.com File Information: '' '' Script Name: abSymMesh v1.1 '' Author: Brendan Ross '' Last Updated: September 21, 2004 '' Update/Change this file at: '' http://www.highend3d.com/maya/mel/?section=modeling#2830 '' '' Please do not alter any information above this line '' it is generated dynamically by Highend3d.com and will '' be changed automatically on any updates. */ /* abSymMesh v 1.1 brendan ross 03.10.2004 www.supercrumbly.com update -- 09.20.2004: "Select Moved Verts" button will select vertices that have been moved relative to the base mesh . use: A useful little script for building symmetrical and asymmetrical blendshapes. Check for symmetry, mirror and flip polygon geometry, and much more. (ok, not much more, but it is pretty useful) directions: It should be fairly self explanatory, but here goes. Select a mesh and click "Check Symmetry" to highlight asymmetric vertices. To use the selection mirror, mirror selected, flip, and revert functions, you must first select a symmetrical mesh and click "Select Base Geometry." You can now select a duplicate mesh with the same structure, and you should be able to use all of the functions on it. Revert, mirror, and flip work on both vertex (component) and object selections. Uncheck "Use Pivot as Origin" to evaluate your objects using the mirror axis world origin as your axis of symmetry. That's it. I hope you find it useful. */ global proc string[] abCheckSym (string $obj, int $axis, float $tol, int $bTable, int $usePiv) { //$bTable is bool to use $obj to create and populate $abSymTable //which goes a little like {obj.vtx[pos mAxis 1], obj.vtx[neg mAxis 1]} global int $abSymTable[]; string $aNegVerts[]; string $aPosVerts[]; string $aNonSymVerts[]; string $aStr[]; string $vtx; string $str; int $aPosVertsInt[]; int $aNegVertsInt[]; int $aInt[]; int $totVtx; int $i; int $j; int $mAxisInd = $axis - 1; //mirror axis index (for xform) int $axis2Ind = ($mAxisInd + 1) % 3; int $axis3Ind = ($mAxisInd + 2) % 3; int $mod; int $prog; int $vertCounter = 0; float $aNegVertTrans[]; float $aPosVertTrans[]; float $aVtxTrans[]; float $aVtx2Trans[]; float $bBox[]; float $mid; float $midOffset; float $posOffset; float $negOffset; float $flt; float $progNum; float $progDenom; float $test1; float $test2; if ($usePiv){ $aVtxTrans = `xform -q -ws -t $obj`; $mid = $aVtxTrans[$mAxisInd]; }else{ if ($bTable){ clear($abSymTable); $bBox = `xform -q -ws -boundingBox $obj`; $mid = $bBox[$mAxisInd] + (($bBox[($mAxisInd+3)] - $bBox[$mAxisInd])/2); }else{ $mid = 0; //if object isn't symmetrical, it's got to be at the origin to measure symmetry } } $aInt = `polyEvaluate -v $obj`; $totVtx = $aInt[0]; waitCursor -state on; progressWindow -title "Working" -progress 0 -status "Sorting"; $progDenom = $totVtx; $flt = ceil($progDenom/50); $mod = $flt; for ($i=0;$i<$totVtx;$i++){ //prog win if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive $progNum = $i; $prog = ($progNum/$progDenom)*100.0; progressWindow -e -progress $prog; } //end prog win $vtx = $obj+".vtx["+$i+"]"; $aVtxTrans = `xform -q -ws -translation $vtx`; $midOffset = $aVtxTrans[$mAxisInd] - $mid; if ($midOffset >= 0){ $aPosVerts[size($aPosVerts)] = $vtx; if ($bTable){$aPosVertsInt[size($aPosVertsInt)] = $i;} $aVtxTrans = `xform -q -ws -t $vtx`; $aPosVertTrans[size($aPosVertTrans)] = $aVtxTrans[$mAxisInd]; }else{ if ($midOffset < 0){ $aNegVerts[size($aNegVerts)] = $vtx; if ($bTable){$aNegVertsInt[size($aNegVertsInt)] = $i;} $aVtxTrans = `xform -q -ws -t $vtx`; $aNegVertTrans[size($aNegVertTrans)] = $aVtxTrans[$mAxisInd]; } } } if ($bTable){$str = "Building Symmetry Table";}else{$str = "Checking For Symmetry";} progressWindow -e -progress 0 -status $str; $progDenom = size($aPosVerts); $flt = ceil($progDenom/50); $mod = $flt; //now find nonsymverts for ($i=0;$i 200){ //show prog if more than this many verts being mirrored $showProg = true; $str = "Mirroring Vertices"; if ($flip){$str = "Flipping Vertices";} progressWindow -title "Working" -progress 0 -status $str; $progDenom = size($aSelVerts); $flt = ceil($progDenom/50); $mod = $flt; } //strip out Pos verts if $negToPos is true (and vice versa) //aposverts (and anegverts) are int arrays in this proc to simplify matching //get pos neg info from base mesh for ($i=0;$i 0){ $aPosVertsInt[size($aPosVertsInt)] = $vertNum; continue; } if ($baseMidOffset < 0){ $aNegVertsInt[size($aNegVertsInt)] = $vertNum; continue; } } if ($negToPos){ $aPosVertsInt = $aNegVertsInt; } if ($showProg){ $progDenom = size($aPosVertsInt); $flt = ceil($progDenom/50); $mod = $flt; } for ($i=0;$i 200){ //show prog if more than this many verts being mirrored $showProg = true; progressWindow -title "Working" -progress 0 -status "Reverting Vertices"; $progDenom = size($aSelVerts); $flt = ceil($progDenom/50); $mod = $flt; } waitCursor -state on; for ($i=0;$i $tol){ $posDif = true; } } if ($posDif) { $aRetSel[size($aRetSel)] = $aVtx2; } } return $aRetSel; } global proc string[] abSelSideVerts (string $obj, string $baseObj, int $mAxisInd, int $selNeg, int $usePiv, float $tol){ //selects a side of the object (located on origin) for faster mirroring (instead of having to find symmetrical verts) //$selNeg true -- select Negative side of mesh, false -- select Pos side, 2 -- select all verts int $aInt[]; int $totVtx; int $i; string $aRetSel[]; //return string of selected verts string $vtxStr; float $aVtxTrans[]; float $bBox[]; float $baseMid; float $baseMidOffset; $mAxisInd -= 1; //from (1 to 3) to (0 to 2) $aInt = `polyEvaluate -v $obj`; $totVtx = $aInt[0]; if ($selNeg == 2){ //return all verts for ($i=0;$i<$totVtx;$i++){ $vtx = $obj+".vtx["+$i+"]"; $aRetSel[size($aRetSel)] = $vtx; } return $aRetSel; } if ($usePiv){ $aVtxTrans = `xform -q -ws -t $baseObj`; $baseMid = $aVtxTrans[$mAxisInd]; }else{ $bBox = `xform -q -ws -boundingBox $baseObj`; $baseMid = $bBox[$mAxisInd] + (($bBox[($mAxisInd+3)] - $bBox[$mAxisInd])/2); } for ($i=0;$i<$totVtx;$i++){ $vtxStr = ".vtx["+$i+"]"; $aVtxTrans = `xform -q -ws -translation ($baseObj+$vtxStr)`; $baseMidOffset = $aVtxTrans[$mAxisInd] - $baseMid; if (abs($baseMidOffset) < $tol){ $aRetSel[size($aRetSel)] = $obj+$vtxStr; continue; } if ($baseMidOffset > 0 && !$selNeg){ $aRetSel[size($aRetSel)] = $obj+$vtxStr; continue; } if ($baseMidOffset < 0 && $selNeg){ $aRetSel[size($aRetSel)] = $obj+$vtxStr; continue; } } return $aRetSel; } global proc string[] abSelMirror (string $obj, string $aSelVerts[]){ //mirror selection (not selected) global int $abSymTable[]; string $aRetVerts[]; string $vtxStr; int $i; int $vertNum; int $mVertNum; if (size($abSymTable) == 0){ warning "No Base Geometry Selected"; return $aSelVerts; } waitCursor -state on; $vtxStr = $obj+".vtx["; for ($i=0;$i 1){ warning "Select one polygon object"; $warned = true; }else{ $selMesh = $aStr[0]; //if an object is selected } //make sure selected components are on only one mesh if ($selMesh == ""){ $aHiliteObj = `ls -hilite`; if (size($aHiliteObj) == 1){ $selMesh = $aHiliteObj[0]; $aSelVerts = `filterExpand -sm 31 $sel`; }else{ if (size($aHiliteObj) > 1){ clear($aSelVerts); warning "Only one object can be hilited in component mode"; $warned = true; } } }else{ select $selMesh; //if two objects are selected } switch ($action){ case "sbgBn": if ($selMesh != ""){ abCheckSym($selMesh, $axisSel, $tol, true, $usePiv); $abSbg = $selMesh; textField -e -text $selMesh sbgFld; button -e -enable true smBn; button -e -enable true smvBn; button -e -enable true msBn; button -e -enable true fsBn; button -e -enable true rsBn; }else{ abClearSbg(); } break; case "favBn": if ($selMesh != ""){ $aSelVerts = abCheckSym($selMesh, $axisSel, $tol, false, $usePiv); if (size($aSelVerts) > 0){ selectMode -component; select $aSelVerts; print (size($aSelVerts)+" asymmetric vert(s)"); }else{ select $selMesh; print ($selMesh+" is symmetrical"); } } break; case "smBn": if (size($aSelVerts) > 0){ $aSelVerts = abSelMirror ($selMesh, $aSelVerts); select $aSelVerts; } break; case "smvBn": if ($selMesh != ""){ $aSelVerts = abSelMovedVerts($selMesh, $baseObj, $tol); select $aSelVerts; } break; case "msBn": if (size($aSelVerts) > 0){ abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, false, $usePiv, $tol); }else{ if ($selMesh != ""){ //if object is selected, select half side verts then pass that as $aSelVerts $aSelVerts = abSelSideVerts ($selMesh, $baseObj, $axisSel, $negToPos, $usePiv, $tol); abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, false, $usePiv, $tol); } } break; case "fsBn": if (size($aSelVerts) > 0){ abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, true, $usePiv, $tol); }else{ if ($selMesh != ""){ //if object is selected, select half side verts then pass that as $aSelVerts $aSelVerts = abSelSideVerts ($selMesh, $baseObj, $axisSel, $negToPos, $usePiv, $tol); abMirrorSel($selMesh, $baseObj, $aSelVerts, $axisSel, $negToPos, true, $usePiv, $tol); } } break; case "rsBn": if (size($aSelVerts) > 0){ abRevertSel($aSelVerts, $selMesh, $baseObj); }else{ if ($selMesh != ""){ //if object is selected, select half side verts then pass that as $aSelVerts $aSelVerts = abSelSideVerts ($selMesh, $baseObj, $axisSel, 2, $usePiv, $tol); //2 returns all verts abRevertSel($aSelVerts, $selMesh, $baseObj); } } break; case "cBn": abClearSbg(); deleteUI -window abSymWin; break; case "saRbGrp": abClearSbg(); switch ($axisSel){ case 1: $str = "X"; break; case 2: $str = "Y"; break; case 3: $str = "Z"; break; } $str = "Operate -"+$str+" to +"+$str; checkBox -e -l $str maChkBx; } } global proc abSymMesh (){ global int $abSymTable[]; global string $abSbg; int $sbgBnsEn = false; //bool for enabled state of sbg dependent buttons string $selBaseGeo; if (size($abSymTable) > 0){ //reselect object whose data is in symTable $selBaseGeo = $abSbg; $sbgBnsEn = true; } if (!`window -exists abSymWin`){ window -t "abSymMesh" -w 180 -h 415 abSymWin; } formLayout -numberOfDivisions 100 abSymForm; radioButtonGrp -numberOfRadioButtons 3 -l1 "YZ" -l2 "XZ" -l3 "XY" -select 1 -columnWidth3 52 52 52 -onCommand "abSymCtl(\"saRbGrp\")" saRbGrp; separator sep1; text -l "Gobal Tolerance" tolTxt; textField -editable true -text ".001" tolFld; separator sep2; button -l "Select Base Geometry" -command "abSymCtl(\"sbgBn\")" sbgBn; textField -editable true -text $selBaseGeo sbgFld; separator sep3; button -l "Check Symmetry" -command "abSymCtl(\"favBn\")" csBn; button -l "Selection Mirror" -enable $sbgBnsEn -command "abSymCtl(\"smBn\")" smBn; button -l "Select Moved Verts" -enable $sbgBnsEn -command "abSymCtl(\"smvBn\")" smvBn; separator sep4; button -l "Mirror Selected" -enable $sbgBnsEn -command "abSymCtl(\"msBn\")" msBn; button -l "Flip Selected" -enable $sbgBnsEn -command "abSymCtl(\"fsBn\")" fsBn; button -l "Revert Selected to Base" -enable $sbgBnsEn -command "abSymCtl(\"rsBn\")" rsBn; checkBox -l "Operate -X to +X" -value true maChkBx; checkBox -l "Use Pivot as Origin" -value true upoChkBx; button -l "Close" -height 24 -command "abSymCtl(\"cBn\")" cBn; int $tMarg = 7; int $lMarg = 5; int $rMarg = 5; int $ctSpc = 5; //control top space int $cbSpc = 20; formLayout -e -attachForm saRbGrp "top" $tMarg -attachForm saRbGrp "left" 18 -attachForm sep1 "left" $lMarg -attachControl sep1 "top" $ctSpc saRbGrp -attachForm sep1 "right" $rMarg -attachForm tolTxt "left" $lMarg -attachControl tolTxt "top" ($ctSpc+2) sep1 -attachControl tolFld "left" $ctSpc tolTxt -attachControl tolFld "top" $ctSpc sep1 -attachForm tolFld "right" $rMarg -attachForm sep2 "left" $lMarg -attachControl sep2 "top" $ctSpc tolFld -attachForm sep2 "right" $rMarg -attachForm sbgBn "left" $lMarg -attachControl sbgBn "top" $ctSpc sep2 -attachForm sbgBn "right" $rMarg -attachForm sbgFld "left" $lMarg -attachControl sbgFld "top" $ctSpc sbgBn -attachForm sbgFld "right" $rMarg -attachForm sep3 "left" $lMarg -attachControl sep3 "top" $ctSpc sbgFld -attachForm sep3 "right" $rMarg -attachForm csBn "left" $lMarg -attachControl csBn "top" $ctSpc sep3 -attachForm csBn "right" $rMarg -attachForm smBn "left" $lMarg -attachControl smBn "top" $ctSpc csBn -attachForm smBn "right" $rMarg -attachForm smvBn "left" $lMarg -attachControl smvBn "top" $ctSpc smBn -attachForm smvBn "right" $rMarg -attachForm sep4 "left" $lMarg -attachControl sep4 "top" $ctSpc smvBn -attachForm sep4 "right" $rMarg -attachForm rsBn "left" $lMarg -attachControl rsBn "top" $ctSpc sep4 -attachForm rsBn "right" $rMarg -attachForm msBn "left" $lMarg -attachControl msBn "top" $ctSpc rsBn -attachForm msBn "right" $rMarg -attachForm fsBn "left" $lMarg -attachControl fsBn "top" $ctSpc msBn -attachForm fsBn "right" $rMarg -attachForm maChkBx "left" $lMarg -attachControl maChkBx "top" $ctSpc fsBn -attachForm upoChkBx "left" $lMarg -attachControl upoChkBx "top" $ctSpc maChkBx -attachForm cBn "left" $lMarg -attachControl cBn "top" $cbSpc upoChkBx -attachForm cBn "right" $rMarg abSymForm ; showWindow abSymWin; }