zoukankan      html  css  js  c++  java
  • abSymMeshMEL.txt

    /*
    abSymMesh v 1.7
    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.
    update -- 3.21.2005: Added progress bar for "Select Moved Verts". I love progress bars.
    update -- 10.12.2006: Added popupMenu to "Revert Selected to Base" button to revert by a given percentage. Added $abSymProgBarThresh to adjust the number of verts included in an operation before a progress bar will be displayed (adjust higher for faster computers).
    update -- 10.25.2006: Added a slider to dynamically revert selected verts to base object. The slider only works on vertex selections, not on the object level (too slow). You can now specify alternate versions of the base mesh to revert to as well. Improved performance of revert.
    update -- 12.04.2006: It should now work in Maya 8.
    update -- 4.12.2008: Added operations menu. Allows you to copy, add and subtract blendshapes from one another.
    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 int $abSymProgBarThresh = 800; //number of verts in an operation beyond which a progress bar is shown (set higher for faster computers)
    global int $abSymTable[];
    global string $abSymRevVertTable[];
    global vector $abSymRevPosTable[];
    global vector $abSymRevBasePosTable[];
    global int $abSymSliderDragging = false; //used to flag when the mouse is dragging a slider
    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;
        float $midOffsetTol = -.0000001;
        if ($usePiv){
            $aVtxTrans = `xform -q -ws -t $obj`;
            $mid = $aVtxTrans[$mAxisInd];
        }else{
            if ($bTable){
                $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
            }
        }
        if ($bTable) clear($abSymTable);
        $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 >= $midOffsetTol){
                $aPosVerts[size($aPosVerts)] = $vtx;
                if ($bTable){$aPosVertsInt[size($aPosVertsInt)] = $i;}
                $aPosVertTrans[size($aPosVertTrans)] = $aVtxTrans[$mAxisInd];
            }else{
                if ($midOffset < $midOffsetTol){
                    $aNegVerts[size($aNegVerts)] = $vtx;
                    if ($bTable){$aNegVertsInt[size($aNegVertsInt)] = $i;}
                    $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<size($aPosVerts);$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 = $aPosVerts[$i];
            $posOffset = ($aPosVertTrans[$i] - $mid);
            if ($posOffset < $tol){
                $aPosVerts[$i] = "m";
                $vertCounter ++;
                continue;
            }
            for ($j=0;$j<size($aNegVerts);$j++){
                if ($aNegVerts[$j] == "m") continue;
                $negOffset = $mid - $aNegVertTrans[$j];
                if ($negOffset < $tol){
                    $aNegVerts[$j] = "m";
                    $vertCounter ++;
                    continue;
                }
                if (abs($posOffset - $negOffset) <= $tol){
                    $aVtxTrans = `xform -q -ws -t $vtx`;
                    $aVtx2Trans = `xform -q -ws -t $aNegVerts[$j]`;
                    $test1 = $aVtxTrans[$axis2Ind] - $aVtx2Trans[$axis2Ind];
                    $test2 = $aVtxTrans[$axis3Ind] - $aVtx2Trans[$axis3Ind];
                    if (abs($test1) < $tol && abs($test2) < $tol){
                        //match
                        if ($bTable){
                            //use this info to build symmetry table
                            $abSymTable[size($abSymTable)] = $aPosVertsInt[$i];
                            $abSymTable[size($abSymTable)] = $aNegVertsInt[$j];
                            $vertCounter += 2;
                        }
                        $aPosVerts[$i] = $aNegVerts[$j] = "m"; //m is for match
                        break;
                    }
                }
            }
        }
        //now strip out "m" from $aPosVerts and $aNegVerts, and we'll have asymmetry
        $aStr = {"m"};
        $aPosVerts = stringArrayRemove($aStr, $aPosVerts);
        $aNegVerts = stringArrayRemove($aStr, $aNegVerts);
        $aNonSymVerts = stringArrayCatenate($aPosVerts, $aNegVerts);
        if ($bTable){
            $int = size($abSymTable) + $vertCounter;
            if ($vertCounter != $totVtx){
                //object is not symmetrical
                warning "Base geometry is not symmetrical, not all vertices can be mirrored";
            }else{
                print "Base geometry is symmetrical";
            }
        }
        progressWindow -endProgress;
        waitCursor -state off;
        return $aNonSymVerts;
    }
    global proc int abGetSymVtx (int $vtxInt){
        //uses abSymTable, returns symmetrical vtx or -1 if failed
        global int $abSymTable[];
        int $mVtxInt = -1;
        int $i;
        for ($i=0;$i<size($abSymTable);$i++){
            if ($vtxInt == $abSymTable[$i]){
                //match
                if (($i % 2) == 0){
                    //even number, match is record above (it's a positive vert)
                    $mVtxInt = $abSymTable[$i+1];
                }else{
                    $mVtxInt = $abSymTable[$i-1];
                }
                break;
            }
        }
        return $mVtxInt;
    }
    global proc abMirrorSel (string $obj, string $baseObj, string $aSelVerts[], int $axis, int $negToPos, int $flip, int $usePiv, float $tol){
        //$axis is 1, 2, 3 -- $negToPos is bool -- true mirrors negative (axis) to positive (axis)
        //$flip is bool -- if true, selVerts are flipped instead of mirrored
        //$usePiv is bool to use pivot on $obj as origin
        global int $abSymTable[];
        global int $abSymProgBarThresh;
        string $aStr[];
        string $str;
        string $vtx;
        string $obj;
        int $aPosVertsInt[];
        int $aNegVertsInt[];
        int $aZeroVertsInt[];
        int $mAxisInd = $axis - 1; //mirror axis index (for xform)
        int $axis2Ind = ($mAxisInd + 1) % 3;
        int $axis3Ind = ($mAxisInd + 2) % 3;
        int $vertNum;
        int $i;
        int $j;
        int $prog;
        int $mod;
        int $showProg = false; //don't show the progress bar
        float $bBox[];
        float $baseMid;
        float $baseMidOffset;
        float $aVtxTrans[];
        float $aFlpVtxTrans[];
        float $mid; //mirror axis midpoint
        float $progNum;
        float $progDenom;
        float $flt;
        if ($usePiv){
            $aVtxTrans = `xform -q -ws -t $obj`;
            $mid = $aVtxTrans[$mAxisInd];
            $aVtxTrans = `xform -q -ws -t $baseObj`;
            $baseMid = $aVtxTrans[$mAxisInd];
        }else{
            $mid = 0;
            $bBox = `xform -q -ws -boundingBox $baseObj`;
            $baseMid = $bBox[$mAxisInd] + (($bBox[($mAxisInd+3)] - $bBox[$mAxisInd])/2);
        }
        waitCursor -state on;
        if (size($aSelVerts) > $abSymProgBarThresh){ //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<size($aSelVerts);$i++){
            //prog win
            if ($showProg){
                if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
                    $progNum = $i;
                    $prog = ($progNum/$progDenom)*50.0;
                    progressWindow -e -progress $prog;
                }
            }
            //end prog win
            $vtx = $aSelVerts[$i];
            //$aVtxTrans = `xform -q -ws -translation $vtx`;
            $vertNum = match("([0-9])+", (match ("([0-9])+\\]", $vtx)));
            $aVtxTrans = `xform -q -ws -translation ($baseObj+".vtx["+$vertNum+"]")`;
            $baseMidOffset = $aVtxTrans[$mAxisInd] - $baseMid;
            if (abs($baseMidOffset) < $tol){
                $aZeroVertsInt[size($aZeroVertsInt)] = $vertNum;
                continue;
            }
            if ($baseMidOffset > 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<size($aPosVertsInt);$i++){
            //prog win
            if ($showProg){
                if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
                    $progNum = $i;
                    $prog = ($progNum/$progDenom)*50.0 + 50;
                    progressWindow -e -progress $prog;
                }
            }
            //end prog win
            $vertNum = abGetSymVtx($aPosVertsInt[$i]);
            if ($vertNum != -1){
                if (!$flip){ //mirror selected
                    $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aPosVertsInt[$i]+"]")`;
                    $aVtxTrans[$mAxisInd] = 2*$mid - $aVtxTrans[$mAxisInd];
                    xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$vertNum+"]");
                }else{ //flip selected
                    $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aPosVertsInt[$i]+"]")`;
                    $aVtxTrans[$mAxisInd] = 2*$mid - $aVtxTrans[$mAxisInd];
                    $aFlpVtxTrans = `xform -q -ws -t ($obj+".vtx["+$vertNum+"]")`;
                    $aFlpVtxTrans[$mAxisInd] = 2*$mid - $aFlpVtxTrans[$mAxisInd];
                    xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$vertNum+"]");
                    xform -ws -t $aFlpVtxTrans[0] $aFlpVtxTrans[1] $aFlpVtxTrans[2] ($obj+".vtx["+$aPosVertsInt[$i]+"]");
                }
            }
        }
        for ($i=0;$i<size($aZeroVertsInt);$i++){ //flip middle verts too
            if ($flip){
                $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aZeroVertsInt[$i]+"]")`;
                $aVtxTrans[$mAxisInd] = 2*$mid - $aVtxTrans[$mAxisInd];
                xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$aZeroVertsInt[$i]+"]");
            }else{
                $aVtxTrans = `xform -q -ws -t ($obj+".vtx["+$aZeroVertsInt[$i]+"]")`;
                $aVtxTrans[$mAxisInd] = $mid;
                xform -ws -t $aVtxTrans[0] $aVtxTrans[1] $aVtxTrans[2] ($obj+".vtx["+$aZeroVertsInt[$i]+"]");
            }
        }
        if ($showProg){progressWindow -endProgress;}
        waitCursor -state off;
    }
    global proc abRevertSel(string $aSelVerts[], string $obj, string $baseObj, float $bias){
        //reverts selected verts to base -os trans -- $bias is the percentage (0-1) to revert from current verts position to the base verts position, 100 taking on the base object's vert positions (original default behaviour) 
        global int $abSymProgBarThresh;
        string $str;
        string $vtx;
        int $vertNum;
        int $i;
        int $prog;
        int $mod;
        int $showProg = false; //don't show the progress bar
        float $aTrans[];
        float $progNum;
        float $progDenom;
        float $flt;
        float $tol = 0;
        vector $vTol = <<$tol, $tol, $tol>>;
        vector $vBaseTrans;
        vector $vObjTrans;
        if ($bias > 1){
            $bias = 1;
        }else if ($bias < 0){
            $bias = 0;
        }
        $bias = 1 - $bias;
        if ($bias < .01) $bias = 0;
        if (size($aSelVerts) > $abSymProgBarThresh){ //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<size($aSelVerts);$i++){
            //prog win
            if ($showProg){
                if (($i % $mod) == 0){ //make the progress bar a bit less resource intensive
                    $progNum = $i;
                    $prog = ($progNum/$progDenom)*100;
                    progressWindow -e -progress $prog;
                }
            }
            //end prog win
            $vtx = $aSelVerts[$i];
            $vertNum = match("([0-9])+", (match ("([0-9])+\\]", $vtx)));
            $aTrans = `xform -q -os -t ($baseObj+".vtx["+$vertNum+"]")`;
            $vBaseTrans = <<$aTrans[0], $aTrans[1], $aTrans[2]>>;
            //bias stuff
            $aTrans = `xform -q -os -t $vtx`;
            $vObjTrans = <<$aTrans[0], $aTrans[1], $aTrans[2]>>;
            if (abs($vObjTrans - $vBaseTrans) > $vTol) xform -os -t ($vBaseTrans.x+($vObjTrans.x-$vBaseTrans.x)*$bias) ($vBaseTrans.y+($vObjTrans.y-$vBaseTrans.y)*$bias) ($vBaseTrans.z+($vObjTrans.z-$vBaseTrans.z)*$bias) $vtx;
            //done
        }
        if ($showProg){progressWindow -endProgress;}   
        waitCursor -state off;
    }
    global proc abSymInteractiveRevertToBase(){
        //responds to revert to base slider movement
        global string $abSymRevVertTable[];
        global vector $abSymRevPosTable[];
        global vector $abSymRevBasePosTable[];
        global int $abSymSliderDragging;
        global string $abAltSbg;
        global string $abSbg;
        int $i;
        int $firstClick = false;
        if ($abSymSliderDragging == false){
            $abSymSliderDragging = true;
            //check to see if selection is the same -- if it is, use the existing $abSymRevPosTable
            string $aStr[], $selObj, $aSelVerts[], $aBaseVerts[];
            int $buildNewTables = true;
            $aStr = `filterExpand -sm 12`;
            if (size($aStr) == 1){
                $selObj = $aStr[0];
            }else{
                $aStr = `ls -hilite`;
                if (size($aStr) == 1){
                    $selObj = $aStr[0];
                }
            }
            $aSelVerts = `filterExpand -sm 31`;
            if ($selObj != "" && size($aSelVerts) > 0){
                if (size($aSelVerts) == size($abSymRevVertTable) && size($abSymRevVertTable) == size($abSymRevBasePosTable)){               
                    $buildNewTables = false;
                    for ($i=0;$i<size($aSelVerts);$i++){
                        if ($aSelVerts[$i] != $abSymRevVertTable[$i]){
                            $buildNewTables = true;
                            break;
                        }
                    }
                }
                if ($buildNewTables){
                    abSymClearRevTables();
                    float $tol = .001;
                    float $aFlt[];
                    string $aBaseVerts[];
                    vector $vector1, $vector2;
                    string $baseObj = ($abAltSbg != "") ? $abAltSbg : $abSbg;
                    //make base verts array
                    for ($i=0;$i<size($aSelVerts);$i++){
                        $aBaseVerts[size($aBaseVerts)] = $baseObj+(`match "\\.vtx\\[([0-9])+]$" $aSelVerts[$i]`);
                    }
                    for ($i=0;$i<size($aSelVerts);$i++){
                        $aFlt = `xform -q -os -translation $aSelVerts[$i]`;
                        $vector1 = <<$aFlt[0], $aFlt[1], $aFlt[2]>>;
                        $aFlt = `xform -q -os -translation $aBaseVerts[$i]`;
                        $vector2 = <<$aFlt[0], $aFlt[1], $aFlt[2]>>;
                        if ((abs($vector1 - $vector2)) > <<$tol, $tol, $tol>>){
                            $abSymRevVertTable[size($abSymRevVertTable)] = $aSelVerts[$i];
                            $abSymRevPosTable[size($abSymRevPosTable)] = $vector1;
                            $abSymRevBasePosTable[size($abSymRevBasePosTable)] = $vector2;
                        }
                    }
                }
            }else{
                abSymClearRevTables();
                warning "Select vertices on one polygon object.";
            }
            $firstClick = true;
        }
        float $bias = `floatSlider -q -v rvrtFltSldr`;
        float $aObjTrans[], $aBaseTrans[];
        vector $vObjTrans, $vBaseTrans;
        if (size($abSymRevVertTable) == size($abSymRevPosTable) && size($abSymRevPosTable) == size($abSymRevBasePosTable)){
            for ($i=0;$i<size($abSymRevVertTable);$i++){
                $vObjTrans = $abSymRevPosTable[$i];
                $vBaseTrans = $abSymRevBasePosTable[$i];
                xform -os -t ($vBaseTrans.x+($vObjTrans.x-$vBaseTrans.x)*$bias) ($vBaseTrans.y+($vObjTrans.y-$vBaseTrans.y)*$bias) ($vBaseTrans.z+($vObjTrans.z-$vBaseTrans.z)*$bias) $abSymRevVertTable[$i];
            }
        }
        if ($firstClick) undoInfo -swf off;
    }
    global proc abSymEndDrag(){
        //called when dragging is done
        global int $abSymSliderDragging;
        $abSymSliderDragging = false;
        undoInfo -swf on;
    }
    global proc abSymClearRevTables(){
        //clears out globals associated with dragging reversion slider
        global string $abSymRevVertTable[];
        global vector $abSymRevPosTable[];
        global vector $abSymRevBasePosTable[];
        clear $abSymRevVertTable;
        clear $abSymRevPosTable;
        clear $abSymRevBasePosTable;
    }
    global proc abSymUseAlternateBase(int $useAltBase){
        //substitute alternate variation of this mesh as the base shape for revert commands -- $useAltBase is a boolean which determines whether to use the alternate base or to revert to original base object
        global string $abAltSbg;
        global string $abSbg;
        string $aStr[];
        int $aInt[], $totNewVtx, $totOrigVtx;
        if ($useAltBase){
            $aStr = `filterExpand -sm 12`;
            if (size($aStr) == 1){
                $aInt = `polyEvaluate -v $abSbg`; 
                $totOrigVtx = $aInt[0];
                $aInt = `polyEvaluate -v $aStr[0]`; 
                $totNewVtx = $aInt[0];
                if ($totOrigVtx = $totNewVtx){
                    //number of verts match up, so accept this mesh as a usable base
                    $abAltSbg = $aStr[0];
                    abSymClearRevTables();
                    menuItem -e -label ("Using "+$abAltSbg+" as Base") abSymCurBsMnIt;
                    menuItem -e -enable true abSymSlOrigRvtBsMnIt;
                    menuItem -e -enable true abSymSlAltMvVtsMnIt;
                }else{
                    warning "The new base mesh must have the same number of vertices as the current base mesh.";
                }
            }else{
                warning "Select a mesh to use as a base object.";
            }
        }else{
            $abAltSbg = "";
            abSymClearRevTables();
            menuItem -e -label "Using Original Base" abSymCurBsMnIt;
            menuItem -e -enable false abSymSlOrigRvtBsMnIt;
            menuItem -e -enable false abSymSlAltMvVtsMnIt;
        }
    }
    global proc string[] abSelMovedVerts(string $obj, string $baseObj, float $tol){
        //select repositioned verts (as compared to the base mesh)
        int $aInt[];
        int $totVtx;
        int $i;
        int $j;
        float $tFlt;
        float $aVtxTrans[];
        string $objStr = $obj+".vtx[";
        string $baseObjStr = $baseObj+".vtx[";
        string $aRetSel[];
        string $vtx;
        vector $vTrans1, $vTrans2;
        vector $vTol = <<$tol, $tol, $tol>>;
        $aInt = `polyEvaluate -v $obj`; 
        $totVtx = $aInt[0];
        int $mod, $prog;
        float $flt, $progNum, $progDenom;
        float $progUpdate = 50.0;
        waitCursor -state on;
        progressWindow -title "Working" -progress 0 -status "Checking Verts";
        $progDenom = $totVtx;
        $flt = ceil($progDenom/$progUpdate);
        $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 = $objStr+$i+"]";
            $aVtxTrans = `xform -q -os -t ($baseObjStr+$i+"]")`;
            $vTrans1 = <<$aVtxTrans[0], $aVtxTrans[1], $aVtxTrans[2]>>;
            $aVtxTrans = `xform -q -os -t $vtx`;
            $vTrans2 = <<$aVtxTrans[0], $aVtxTrans[1], $aVtxTrans[2]>>;
            if (abs($vTrans1 - $vTrans2) > $vTol) $aRetSel[size($aRetSel)] = $vtx;
        }
        progressWindow -endProgress;
        waitCursor -state off;
        return $aRetSel;
    }
    global proc abSMServiceAddSubtractCopy(int $operation){
        // called by add, subtract and copy buttons in the menu -- if selection and basemesh are in order it calls abSMAddSubtractCopyMesh
        // operation is passed to abSMAddSubtractCopyMesh
        global string $abSbg;
        if ($abSbg == ""){
            warning "You must select a base mesh first.";
            return;
        }
        string $aSel[] = `ls -sl`;
        if (size($aSel) != 2){
            warning "Select two mesh objects (source and target).";
            return;
        }
        string $mesh, $aRel[];
        int $aInt[] = `polyEvaluate -v $abSbg`; 
        int $baseVertNum = $aInt[0];
        // make sure that both objects are meshes with the correct number of verts (same as base mesh) and neither is the basemesh
        for ($mesh in $aSel){
            // make sure neither mesh is the base mesh
            if ($mesh == $abSbg){
                warning "The basemesh cannot be used as a source or target. Try using revert instead.";
                return;
            }
            $aRel = `listRelatives -type mesh`;
            if (size($aRel) == 0){
                warning ($mesh+" is not a mesh. Unable to proceed.");
                return;
            }else{
                $aInt = `polyEvaluate -v $mesh`;
                if ($aInt[0] != $baseVertNum){
                    warning ($mesh+" topology doesn't match the base object. Unable to proceed.");
                    return;
                }
            }
        }
        // ok, it's good to go
        abSMAddSubtractCopyMesh($abSbg, $aSel[0], $aSel[1], $operation);
    }
    global proc abSMAddSubtractCopyMesh(string $baseMesh, string $source, string $target, int $operation){
        // adds or subtracts one blend ($source) from another ($target) based on operation (0 == subtract, 1 == add, 2 == copy)
        int $aInt[], $totVtx, $i;
        float $aBaseVtxTrans[], $aSourceVtxTrans[], $aTargetVtxTrans[], $aSourceBaseOffset[];
        string $baseMeshStr = $baseMesh+".vtx[";
        string $sourceMeshStr = $source+".vtx[";
        string $targetMeshStr = $target+".vtx[";
        $aInt = `polyEvaluate -v $baseMesh`; 
        $totVtx = $aInt[0];
        // get offset of source verts from baseMesh
        for ($i=0;$i<$totVtx;$i++){
            $aBaseVtxTrans = `xform -q -os -t ($baseMeshStr+$i+"]")`;
            $aSourceVtxTrans = `xform -q -os -t ($sourceMeshStr+$i+"]")`;
            $aTargetVtxTrans = `xform -q -os -t ($targetMeshStr+$i+"]")`;
            $aSourceBaseOffset = {$aSourceVtxTrans[0]-$aBaseVtxTrans[0], $aSourceVtxTrans[1]-$aBaseVtxTrans[1], $aSourceVtxTrans[2]-$aBaseVtxTrans[2]};
            if ($operation == 0){
                // subtract
                $aTargetVtxTrans = {$aTargetVtxTrans[0]-$aSourceBaseOffset[0], $aTargetVtxTrans[1]-$aSourceBaseOffset[1], $aTargetVtxTrans[2]-$aSourceBaseOffset[2]};
            }else if ($operation == 1){
                // add
                $aTargetVtxTrans = {$aTargetVtxTrans[0]+$aSourceBaseOffset[0], $aTargetVtxTrans[1]+$aSourceBaseOffset[1], $aTargetVtxTrans[2]+$aSourceBaseOffset[2]};
            }else if ($operation == 2){
                // copy
                $aTargetVtxTrans = $aSourceVtxTrans;
            }
            xform -os -t $aTargetVtxTrans[0] $aTargetVtxTrans[1] $aTargetVtxTrans[2] ($targetMeshStr+$i+"]");
        }
    }
    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<size($aSelVerts);$i++){
            $vertNum = match("([0-9])+", (match ("([0-9])+\\]", ($vtxStr+$aSelVerts[$i]+"]"))));
            $mVertNum = abGetSymVtx($vertNum);
            if ($mVertNum != -1){
                $aRetVerts[size($aRetVerts)] = ($vtxStr+$mVertNum+"]");
            }else{ //return non symverts too (zeros and others)
                $aRetVerts[size($aRetVerts)] = ($vtxStr+$vertNum+"]");
            }
        }
        waitCursor -state off;
        return $aRetVerts;
    }
    global proc abClearSbg (){
        //clears sbgFld and empties $abSymTable
        global int $abSymTable[];   
        global string $abSbg;
        global string $abAltSbg;
        button -e -enable false smBn;
        button -e -enable false smvBn;
        button -e -enable false msBn;
        button -e -enable false fsBn;
        button -e -enable false rsBn;
        clear($abSymTable);
        $abSbg = $abAltSbg = "";
        textField -e -text "" sbgFld;
    }
    global proc abSymCtl (string $action){
        global int $abSymTable[];
        global string $abSbg;
        global string $abAltSbg;
        string $sel[] = `ls -sl -fl`;
        string $aStr[];
        string $aSelVerts[];
        string $aHiliteObj[];
        string $baseObj = $abSbg;
        string $revertBaseObj = ($abAltSbg != "") ? $abAltSbg : $abSbg;
        string $str;
        string $selMesh;
        float $tol = `floatField -q -value tolFltFld`;
        int $axisSel = `radioButtonGrp -q -select saRbGrp`;
        int $negToPos = `checkBox -q -value maChkBx`;
        int $usePiv = `checkBox -q -value upoChkBx`;
        int $warned = false; //set if warning has already been passed
        float $revertBias = 1;
        if ($action == "rsPrBn"){
            $revertBias = `floatField -q -value rsPrFltFld`;
            $action = "rsBn";
        }
        //get selection info
        $aStr = `filterExpand -sm 12 $sel`;
        if (size($aStr) > 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 "smvAltBn":
                if ($selMesh != ""){
                    $aSelVerts = abSelMovedVerts($selMesh, $revertBaseObj, $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, $revertBaseObj, $revertBias);
                }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, $revertBaseObj, $revertBias);
                    }
                }
                break;
            case "cBn":
                abClearSbg();
                abSymClearRevTables();
                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;
        }
        setFocus "modelPanel1";
    }
    global proc abSymMesh (){
        global int $abSymTable[];
        global string $abSbg;
        global string $abAltSbg;
        global int $abSymSliderDragging;
        $abSymSliderDragging = false;
        abSymClearRevTables();
        float $aRevertPopupVals[] = {1,2,3,4,5,1111,10,20,30,40,50,60,70,80,90}; //values that will appear in the revert popup menu (1111 is a divider bar)
        int $sbgBnsEn = false; //bool for enabled state of sbg dependent buttons
        string $selBaseGeo;
        if (size($abSymTable) > 0 && `objExists $abSbg`){ //reselect object whose data is in symTable
            $selBaseGeo = $abSbg;
            $sbgBnsEn = true;
        }else{
            clear($abSymTable);
            $abSbg = $abAltSbg = "";
        }
        if (`window -exists abSymWin`){
            deleteUI -window abSymWin;
        }
        window -t "abSymMesh" -w 180 -h 474 -menuBar true abSymWin;
        // add menu
        menu -label "Operations" -postMenuCommand "global string $abSbg; menuItem -e -en ($abSbg != \"\") abSMOpCopyMnIt; menuItem -e -en ($abSbg != \"\") abSMOpAddMnIt; menuItem -e -en ($abSbg != \"\") abSMOpSubtractMnIt;" abSMOperationsMn;
        menuItem -label "Copy A to B" -command "abSMServiceAddSubtractCopy(2);" abSMOpCopyMnIt;
        menuItem -label "Add A to B" -command "abSMServiceAddSubtractCopy(1);" abSMOpAddMnIt;
        menuItem -label "Subtract A from B" -command "abSMServiceAddSubtractCopy(0);" abSMOpSubtractMnIt;
        // continue with layout
        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 "Global Tolerance" tolTxt;
        floatField -min 0 -max 1 -value .001 tolFltFld;
        separator sep2;
        button -l "Select Base Geometry" -command "abSymCtl(\"sbgBn\")" sbgBn;
        textField -editable false -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;
        floatSlider -value 1 -minValue 0 -maxValue 1 -dragCommand "abSymInteractiveRevertToBase();" -changeCommand "abSymEndDrag();" rvrtFltSldr;
        popupMenu -button 3 -p rvrtFltSldr rsPpUpMn;
        menuItem -label "Commit Changes" -command "abSymClearRevTables();";
        separator sep5;
        checkBox -l "Operate -X to +X" -value false maChkBx;
        checkBox -l "Use Pivot as Origin" -value true upoChkBx;
        button -l "Close" -height 24 -command "abSymCtl(\"cBn\")" cBn;
        //hidden var field
        floatField -value 1 -min 0 -max 1 -pre 2 -manage 0 rsPrFltFld;
        //revert button popup menus
        popupMenu -button 3 -p rsBn rsPpUpMn;
        if (size($aRevertPopupVals) > 0){
            int $i;
            string $cmdStr;
            float $flt;
            for ($i=0;$i<size($aRevertPopupVals);$i++){
                if ($aRevertPopupVals[$i] == 1111){
                    $cmdStr += "menuItem -divider true;";
                    continue;
                }
                $flt = $aRevertPopupVals[$i]/100;
                $cmdStr += "menuItem -label \""+$aRevertPopupVals[$i]+"%\" -command \"floatField -e -value "+$flt+" rsPrFltFld;abSymCtl(\\\"rsPrBn\\\");\";";
            }
            $cmdStr += "menuItem -divider true;";
            eval($cmdStr);
        }
        setParent -m rsPpUpMn;
        string $baseStr;
        int $enableOrigRecall = false;
        if ($abAltSbg != "" && `objExists $abAltSbg`){
            $baseStr = "Using "+$abAltSbg+" as Base";
            $enableOrigRecall = true;
        }else{
            $baseStr = "Using Original Base";
        }
        menuItem -label $baseStr abSymCurBsMnIt;
        menuItem -divider true;
        menuItem -label "Use Selected as Base" -command "abSymUseAlternateBase(1);" abSymSlRvtBsMnIt;
        menuItem -label "Use Original Base" -enable $enableOrigRecall -command "abSymUseAlternateBase(0);" abSymSlOrigRvtBsMnIt;
        menuItem -label "Select Moved from Revert Base" -enable $enableOrigRecall -command "abSymCtl(\"smvAltBn\");" abSymSlAltMvVtsMnIt;
        menuItem -divider true;
        menuItem -label "Use Overshoot" -checkBox 0 -command "float $min,$max;if (`menuItem -q -c abSymOvrShtMnIt`){$min=-.5;$max=1.5;}else{$min=0;$max=1;}floatSlider -e -min $min -max $max rvrtFltSldr;" abSymOvrShtMnIt;
        setParent ..;
        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 tolFltFld "left" $ctSpc tolTxt
            -attachControl tolFltFld "top" $ctSpc sep1
            -attachForm tolFltFld "right" $rMarg
            -attachForm sep2 "left" $lMarg
            -attachControl sep2 "top" $ctSpc tolFltFld
            -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 msBn "left" $lMarg
            -attachControl msBn "top" $ctSpc sep4
            -attachForm msBn "right" $rMarg
            -attachForm fsBn "left" $lMarg
            -attachControl fsBn "top" $ctSpc msBn
            -attachForm fsBn "right" $rMarg
            -attachForm sep5 "left" $lMarg
            -attachControl sep5 "top" $ctSpc fsBn
            -attachForm sep5 "right" $rMarg
            -attachForm rsBn "left" $lMarg
            -attachControl rsBn "top" $ctSpc sep5
            -attachForm rsBn "right" $rMarg
            -attachForm rvrtFltSldr "left" $lMarg
            -attachControl rvrtFltSldr "top" $ctSpc rsBn
            -attachForm rvrtFltSldr "right" $rMarg
            -attachForm maChkBx "left" $lMarg
            -attachControl maChkBx "top" ($ctSpc+4) rvrtFltSldr
            -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;
    }
    abSymMesh ;




  • 相关阅读:
    Dubbo 节点telnet测试
    node.js 文件下载
    node.js获取ip及mac
    excel中根据A列筛选B列填充C列
    django在读取数据库时未筛选到符合条件的记录会报错
    django分页功能
    django中命令行调试程序
    Python中if-else的多种写法
    python自定义函数的参数之四种表现形式
    python类变量和实例变量的区别
  • 原文地址:https://www.cnblogs.com/xe2011/p/2535593.html
Copyright © 2011-2022 走看看