Home Technical Talk

Maya MEL Scale UV shells locally script for anyone that wants it

polycounter lvl 3
Offline / Send Message
Sean_P polycounter lvl 3

NOTE: look to the bottom of the thread for updates on the script


I wanted to locally scale some UV shells and found that Maya didn't have the functionality so i wrote a script to do it.  I included a lot of info about the script so people can use it to learn about splitting an array, appending to an array, get min and max value from and array of floats and finding the pivot point of a shell(the bulk of the script).  A lot of this was hard to find or non existent on the net and I had to figure it out by myself.  Therefore I'm just putting this up so if people face similar issues it will only be a simple google search and not a day of heartache.

Now about the script itself.

Scaling shells:

All Maya can do by Default...(smacks head)


What my script does

Edit: firefox definitely doesn't like the code format.


The Script:

//select one uv point in each shell you would like to scale

//assign Shells into a list and determine how many selected string $uvshelllistt[] = `ls -sl -fl`; int $shellselSize = `size($uvshelllistt)`;

//a loop that goes through each shell one at a time //converts to a uvshell, finds the centre pivot point //and scales the mesh due to the input for($L = 0; $L < $shellselSize; $L++) { //selects uvpoint select -r $uvshelllistt[$L]; //convert shell to shell of uvpoints polySelectBorderShell 0; //create an array of all UV locations float $uvvalues[] =`polyEditUV -q`; //number of values in array of all locations, used for the looping int $selSize = `size ($uvvalues)`; //This next bit will split the array of both UV values into 2 //with only the u and v values in each array using every second //number starting from different points as the main procedure float $Uarray[]; float $Varray[]; //loop for U array starting from the first number for($u = 0; $u < $selSize; $u++) { $Uarray[size($Uarray)] = $uvvalues[$u]; $u=$u+1; } //loop for V array starting from the second number for($v = 1; $v < $selSize; $v++) { $Varray[size($Varray)] = $uvvalues[$v]; $v=$v+1; } //sort both arrays into acending order so first number will //be the lowest (min) U or V value and the last the highest (max) $Uarray = `sort $Uarray`; $Varray = `sort $Varray`; //only need to find the size of one array //they both have the same number of values //i use this to select the last number in the array int $UarraySize = `size ($Uarray)`;
//Max number in U array float $maxNuU = $Uarray[$UarraySize-1]; //Max number in V array float $maxNuV = $Varray[$UarraySize-1]; //Min number in U array float $minNuU = $Uarray[0]; //Min number in V array float $minNuV = $Varray[0]; //get the average of the range to define pivot float $middleU = ($maxNuU + $minNuU)/2; float $middleV = ($maxNuV + $minNuV)/2; //scale with the pivot we have defined polyEditUVShell -pu $middleU -pv $middleV -su .99 -sv .99; } //restore selection to user selected allowing you to re-run command select -r $uvshelllistt;

Replies

  • Add3r
    Offline / Send Message
    Add3r polycounter lvl 11
    Dope, something I had actually been looking at figuring out myself in my spare time.  This is something that has always bugged me with Maya's tools since I usually only pack my unwrapped models in its UV editor.  Thank you sir :) 
  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3
    I'm glad it helps, working with mel in the UV space isn't fun
  • Deadly Nightshade
    Offline / Send Message
    Deadly Nightshade polycounter lvl 10
    Congrats on your first(?) script! I know what you've gone through - I've been where you are myself: looking at the Maya UV editor and realize just how limited it is. Relative transforms on multi-shell selections is just one thing out of many that is missing.

    I disagree though that the information is hard to find. I would argue that it's much more about knowing where and how to find said information. In fact, the Maya commands documentation (as well as the PyMEL documentation) is really good. I doubt you've missed it but I'll post it here for others: http://help.autodesk.com/cloudhelp/2016/ENU/Maya-Tech-Docs/Commands/

    As for dealing with Maya programming problems, this forum has been of great aid to me over the years:
    http://forums.cgsociety.org/forumdisplay.php?f=89

    Feedback:
    -You are overcomplicating things by dividing things into two arrays. Instead you could use something like a matrix.
    -Avoid using the select command inside loops as it is "expensive" - especially when working on mesh components (vertices, UV's, etc). It's amazing how much you can reduce execution time by eradicating select from your code by using other commands (ls, polyListComponentConversion, polySelectConstraint and so on).
    -For more speed, code in PyMEL. You can learn Python here: http://www.codeacademy.com
    If you want to do more coding in Maya then my recommendation is to move away from MEL when you are more comfy with it. Most people think that MEL is a poor language.
    -For even more speed, create custom classes for points, lines, polygons and do computations with them, before manipulating "actual" components in the scene.
    -You can't present code like this with the horrible formatting of one quotebox per line of code - it's difficult to read :(

    Edit:
    If you want another coding challenge, try recreating one of the core features of my tool (Orient shells for example):
    https://www.youtube.com/watch?v=mDOP6d-Fkdw

  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3
    Hey Deadly NIghtshade,

    Definitely first script in the UV space, i find the difference is night and day with the 3d space (querying a pivot point or even the fact that ordered selection doesn't work with uv points)

    I was looking for the local scaling functionality a couple of days ago and saw your script but every time i went onto creative crash there was a server error so i thought i could wait or figure it out myself.

    The commands themselves aren't hard to find but  information on finding the minimum and maximum value in an array (with MEL), didn't find anything on that.

    Cgsociety is definitely a great website and has been a help to me as well.

    100% agree python is the way to go in the future.

    I love the feedback, and i agree the formatting looks terrible, which i think has something to do with firefox.


    p.s. already have a script for that thanks to http://polycount.com/discussion/156560/scripting-beginnerhttp://



  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3
    I was able to shorten/cleanup up the script using the polyEvaluate -bc2 command

    Deadly Nightshade, I'm very intrigued about removing the select command to improve performance, but i haven't got the slightest idea on how

    //select one uv point in each shell you would like to scale

    //assign Shells into a list and determine how many selected
    string $uvshelllistt[] = `ls -sl -fl`;
    int $shellselSize = `size($uvshelllistt)`;

    //a loop that goes through each shell one at a time
    //converts to a uvshell, finds the centre pivot point
    //and scales the mesh due to the input
    for($L = 0; $L < $shellselSize; $L++) {
    //selects uvpoint
    select -r $uvshelllistt[$L];
    //convert shell to shell of uvpoints
    polySelectBorderShell 0;
    //finds out the uv coordinates of a bounding box in uvspace
    float $BC2var[] = `polyEvaluate -bc2 -ae`;
    //create pivot from bounding box coordinites
    float $middleU = ($BC2var[0] + $BC2var[1])/2;
    float $middleV = ($BC2var[2] + $BC2var[3])/2;
    //scale with the pivot we have defined
    polyEditUVShell -pu $middleU -pv $middleV -su .99 -sv .99;
    }
    //restore selection to user selected allowing you to re-run command

    select -r $uvshelllistt;

  • Flynny
    Offline / Send Message
    Flynny polycounter lvl 9
    I just remade this tool in python for an artist: 

    http://pastebin.com/fL6CCrzZ

    http://imgur.com/a/9fyLj


    Enjoy.
  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3
     Flynny said:
    I just remade this tool in python for an artist: 

    http://pastebin.com/fL6CCrzZ

    http://imgur.com/a/9fyLj


    Enjoy.

    I like how you used face selection, probably a bit faster than selecting the UV vert

    I hope this thread helped in the development of the tool :)

  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3

    After seeing Flynny use face selection I have modified my script to take any input, face, edge, vert, uv.  However uvshell is not supported (maya why?).

    So basically you can select one face or edge or vert or uv point in each shell you want to scale and it will work.

    important if you select more than 1 in each shell it will cause the script to scale that shell twice


    //select one uv point in each shell you would like to scale<br><br>//assign Shells into a list and determine how many selected<br>string $uvshelllistt[] = `ls -sl -fl`;<br>int $shellselSize = `size($uvshelllistt)`;<br><br><br>//a loop that goes through each shell one at a time<br>//converts to a uvshell, finds the centre pivot point <br>//and scales the mesh due to the input<br>for($L = 0; $L < $shellselSize; $L++) {&nbsp; <br>//selects uvpoint<br>select -r $uvshelllistt[$L];<br><br>//convert whatever type of selection (face, edge, vert, uv) to uv<br>textureWindowSelectConvert 4;<br><br>//convert shell to shell of uvpoints<br>polySelectBorderShell 0;<br><br>float $BC2var[] = `polyEvaluate -bc2`;<br>float $middleU = ($BC2var[0] + $BC2var[1])/2;<br>float $middleV = ($BC2var[2] + $BC2var[3])/2;<br><br><br>//scale with the pivot we have defined<br>polyEditUVShell -pu $middleU -pv $middleV -su .99 -sv .99;<br>}<br>//restore selection to user selected allowing you to re-run command <br><br><br>select -r $uvshelllistt;



  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3
    Have gone through and made some improvements
    basically now there is a progress bar in the main window (bottom left corner)
    you can cancel the script with the escape key
    if you use edge selection you remain in edge selection mode and so on for the other selection modes

    <br>//select one uv point,face,vert or edge in each shell you would like to scale<br>//if you select more than one in each shell it will run the script twice for that shell<br>//assign Shells into a list and determine how many selected<br>string $uvshelllistt[] = `ls -sl -fl`;<br>int $shellselSize = `size($uvshelllistt)`;<br><br>//uses the progress bar in the main window<br>progressBar -edit -beginProgress -isInterruptable true -status "Processing ..." -maxValue $shellselSize $gMainProgressBar;<br><br>//a loop that goes through each shell one at a time<br>//converts to a uvshell, finds the centre pivot point <br>//and scales the mesh due to the input<br>for($L = 0; $L < $shellselSize; $L++) {&nbsp; <br>//allows you to cancel during the running of the script<br>&nbsp;&nbsp;&nbsp; if(`progressBar -query -isCancelled $gMainProgressBar`)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>//proceeds one step out of however many selections you made giving you a percentage<br>progressBar -edit -step 1 $gMainProgressBar;<br><br>//selects uvpoint<br>select -r $uvshelllistt[$L];<br><br>//convert whatever type of selection (face, edge, vert, uv) to uv<br>textureWindowSelectConvert 4;<br><br>//convert shell to shell of uvpoints<br>polySelectBorderShell 0;<br><br>float $BC2var[] = `polyEvaluate -bc2`;<br>float $middleU = ($BC2var[0] + $BC2var[1])/2;<br>float $middleV = ($BC2var[2] + $BC2var[3])/2;<br><br>//scale with the pivot we have defined<br>polyEditUVShell -pu $middleU -pv $middleV -su .99 -sv .99;<br>}<br><br>//closes progress bar after loop is complete<br>progressBar -edit<br>&nbsp;&nbsp;&nbsp; -endProgress<br>&nbsp;&nbsp;&nbsp; $gMainProgressBar;<br>//used the list selection to determine what selection mode you used and converts yo back to it after using uv points<br>if (`gmatch $uvshelllistt[0] "*.vtx*"`)<br>PolySelectConvert 3;<br>if (`gmatch $uvshelllistt[0] "*.e*"`)<br>PolySelectConvert 2;<br>if (`gmatch $uvshelllistt[0] "*.f*"`)<br>PolySelectConvert 10;<br><br>//restore selection to user selected allowing you to re-run command <br>select -r $uvshelllistt;<br>
  • Sean_P
    Offline / Send Message
    Sean_P polycounter lvl 3
    I've updated this tool
    now you can use a slider to scale, you can scale down or back up to original, it remembers the original scale</code><br><br><img title="Image: https://us.v-cdn.net/5021068/uploads/editor/fc/3ii3htscacmj.gif" src="https://us.v-cdn.net/5021068/uploads/editor/fc/3ii3htscacmj.gif" alt=""><br><br><pre class="CodeBlock"><code><code><code>//Global variable declaration
    <p>global string $uvshelllistt2[];</p>
    <p>global float $equasionout = 1;</p>
    <p>global float $scaleamount = 1;</p>
    <p><br></p>
    <p>//Window commands</p>
    <p>$window = `window -h 30 -w 50 -t "Local Scale"  -s off -tlc 200 500`;</p>
    <p>rowColumnLayout -cw 10 10;</p>
    <p>text -l "";</p>
    <p>text -l "Local Scale Tool";</p>
    <p>text -l "";</p>
    <p>floatSliderGrp -cc "changenumber" -ss 0.01 -cw3 40 40 150 -v 1 -minValue 0.1 -maxValue 1.000 -label "Scale" -field true slider1;</p>
    <p>showWindow;</p>
    <p><br></p>
    <p>//procedure driven by slider</p>
    <p>proc changenumber()</p>
    <p>{</p>
    <p>//Global variable declaration</p>
    <p>global string $gMainProgressBar;    </p>
    <p>global float $scaleamount;</p>
    <p>global float $equasionout;</p>
    <p>global string $uvshelllistt2[];</p>
    <p>//assign Shells into a list and determine how many selected</p>
    <p>string $uvshelllistt[] = `ls -sl -fl`;</p>
    <p>int $shellselSize = `size($uvshelllistt)`;</p>
    <p>//this check to see if the selection has changed and </p>
    <p>//if so will reset the scale back to 1</p>
    <p>if ($uvshelllistt[0]!=$uvshelllistt2[0]){</p>
    <p>$scaleamount = 1;</p>
    <p>}</p>
    <p>$uvshelllistt2 = $uvshelllistt;</p>
    <p>//Variables that use some simple math to scale and keep track of scale</p>
    <p>float $inputnum1 = `floatSliderGrp -q -value slider1`;</p>
    <p>float $equasionout = $inputnum1/$scaleamount;</p>
    <p>float $scaleamount = $scaleamount*$equasionout;</p>
    <p>//uses the progress bar in the main window</p>
    <p>progressBar -edit -beginProgress -isInterruptable true -status "Processing ..." -maxValue $shellselSize $gMainProgressBar;</p>
    <p>//a loop that goes through each shell one at a time</p>
    <p>//converts to a uvshell, finds the centre pivot point </p>
    <p>//and scales the mesh due to the input</p>
    <p>for($L = 0; $L < $shellselSize; $L++) {  </p>
    <p>//allows you to cancel during the running of the script</p>
    <p>    if(`progressBar -query -isCancelled $gMainProgressBar`)</p>
    <p>        break;</p>
    <p>//proceeds one step every loop out of however many selections you made (progress bar)</p>
    <p>progressBar -edit -step 1 $gMainProgressBar;</p>
    <p>//selects uvpoint</p>
    <p>select -r $uvshelllistt[$L];</p>
    <p>//convert whatever type of selection (face, edge, vert, uv) to uv</p>
    <p>textureWindowSelectConvert 4;</p>
    <p>//convert uv point to shell of uvpoints</p>
    <p>polySelectBorderShell 0;</p>
    <p>//Calculates centre of shell (pivot)</p>
    <p>float $BC2var[] = `polyEvaluate -bc2`;</p>
    <p>float $middleU = ($BC2var[0] + $BC2var[1])/2;</p>
    <p>float $middleV = ($BC2var[2] + $BC2var[3])/2;</p>
    <p>//scale using the pivot  and the scale we have defined</p>
    <p>polyEditUVShell -pu $middleU -pv $middleV -su $equasionout -sv $equasionout;</p>
    <p>}</p>
    <p>//at 100% completion close progress bar</p>
    <p>progressBar -edit</p>
    <p>    -endProgress</p>
    <p>    $gMainProgressBar;</p>
    <p><br></p>
    <p>//checking to see what selection mode you used and restoring selection mode</p>
    <p>if (`gmatch $uvshelllistt[0] "*.vtx*"`)</p>
    <p>PolySelectConvert 3;</p>
    <p>if (`gmatch $uvshelllistt[0] "*.e*"`)</p>
    <p>PolySelectConvert 2;</p>
    <p>if (`gmatch $uvshelllistt[0] "*.f*"`)</p>
    <p>PolySelectConvert 10;</p>
    <p>//restore selection to user selected and allowing you to re-run command</p>
    <p>select -r $uvshelllistt;</p>
    <p>}<br></p><pre class="CodeBlock"><code><p>global string $gMainProgressBar;</p><p><br></p>
  • Maddog4america
    Offline / Send Message
    Maddog4america polycounter lvl 5
    Is there a way to drag and select all the uv shells instead of selecting one point from the shell?  When selecting all the points it scales weird.   It would be nice if you could scale all of them really quickly from a drag select all
  • oglu
    Offline / Send Message
    oglu polycount lvl 666
    Is there a way to drag and select all the uv shells instead of selecting one point from the shell?  When selecting all the points it scales weird.   It would be nice if you could scale all of them really quickly from a drag select all
    YES please
Sign In or Register to comment.