[Maya/Mel] UDIM uv patch selection. Syntax help please

global proc selectUDIMPatchalt(){ 
    polySelectConstraint -m 3 -t 0x0010 -d 1 -dp 0.5 0.5 0 -db 0 0.7075; // select uv covering the whole tile.
    resetPolySelectConstraint;
    string $ConstraintSel[] = `ls -sl -fl`; //store initial selection
    int $minU = 0; //later will be replaced with intfield query
    int $minV = 0;
    int $maxU = 1;
    int $maxV = 1;
    string $finalUV[];
    int $uvLoc[];
        for($i = 0; $i < size($ConstraintSel) ; $i++) { //testing uvs against bounding box
           $uvLoc[$i] = `polyEditUV -q -u -v $ConstraintSel`;
               if ($uvLoc[$i] > $minU && $uvLoc[$i] < $maxU)($uvLoc[$i+1] > $minV && $uvLoc[$i+1] < $maxV){
                   $finalUV[$i] = $ConstraintSel[$i];
                    }
    print $finalUV;
}

selectUDIMPatchalt;

This script is suppose to select a UDIM uv patch based on user specified number.
Right now Im using poly selection constraint to select uvs base on a point in uv space, the parameter controlling the selection is based on distance from the point currently set as 0.7075 max range.
When it runs it will select uvs in a radial shape. With this number it will overshoot beyond the tile border a bit. Then with the for loop, I test the uv selection to see if it lies within the tile. If it is, then it will store in a array. Then finally I would convert the selection to uv shell.

Unfortunately i run into a syntax error running the above code. Any maya wizards out there that can help me with this issue. Thanks

update: solved the syntax error. I was missing a closing } bracket. Also changed the if statement by replacing the )( to && in between “$maxU $uvLoc[$i+1]”. But new error arises.

// Error: line 12: Cannot convert data of type float[] to type float. //


global proc selectUDIMPatchalt(){ 
    polySelectConstraint -m 3 -t 0x0010 -d 1 -dp 0.5 0.5 0 -db 0 0.7075; // select uv covering the whole tile.
    resetPolySelectConstraint;
    string $ConstraintSel[] = `ls -sl -fl`; //store initial selection
    int $minU = 0;
    int $minV = 0;
    int $maxU = 1;
    int $maxV = 1;
    string $finalUV[];
    float $uvLoc[];
        for($i = 0; $i < size($ConstraintSel) ; $i++) { //start testing uvs against bounding box
           $uvLoc[$i] = `polyEditUV -q -u -v $ConstraintSel[$i]`;
               if ($uvLoc[$i] > $minU && $uvLoc[$i] < $maxU && $uvLoc[$i+1] > $minV && $uvLoc[$i+1] < $maxV){
                   $finalUV[$i] = $ConstraintSel[$i];
                    }
                    print $finalUV;
        }
    
}

selectUDIMPatchalt;

After thoroughly looking at my code. I realized that the main problem is in the if statement and the for loop parameters. Because “polyEditUV -q” gives a pair of values for location. The U is stored in odd numbers and V stored in even numbers. Therefore I separated the if statements into 2, using “%” to test for even or odd numbers. Strange thing is when I run the current code, if seems to ignore my if statements. not sure why. I would appreciate it if someone can give me some pointers.


global proc selectUDIMPatchalt(){ 
    polySelectConstraint -m 3 -t 0x0010 -d 1 -dp 0.5 0.5 0 -db 0 0.7075; // select uv covering the whole tile with some tile overlap due to radial selection. 
    resetPolySelectConstraint;
    string $ConstraintSel[] = `ls -sl -fl`; //store initial selection
    select -clear;
    int $minU = 0;
    int $minV = 0;
    int $maxU = 1;
    int $maxV = 1;
    string $finalUV[]; //variable for storing UV selection after testing
    int $numUVs = `size $ConstraintSel`;
    float $uvLoc[];
        for($i = 0; $i < ($numUVs*2); $i++) { // *2 because uv location is store as pairs, odd number for u, even number for v
           $uvLoc = `polyEditUV -q -u -v $ConstraintSel`; //store u and v location for each uv in $ConstraintSel
           }
           
        for($j = 0; $j < $numUVs; $j++){
               if (($j % 2 == 1) && ($uvLoc[$j] > $minU) && ($uvLoc[$j] < $maxU)){ //odd number testing
                   $finalUV = $ConstraintSel;
                  }
                  
               if (($j % 2 == 0) && ($uvLoc[$j] > $minV) && ($uvLoc[$j] < $maxV)){ //even number testing
                   $finalUV = $ConstraintSel;
               }
        }
        print $finalUV;
        select $finalUV;
}

selectUDIMPatchalt;

Is this an ‘inside the range’ test or an ‘outside the range’ test? It looks like your code is asking 'is this U inside (min, max) or is this V inside (min, max), which will select things that are valid in one or two dimensions.

Plus, you’re not appending to the $finalUV selection, so it will only ever show the results for the last item that meets the criterion.

Here’s a python version which does what I think you’re looking for:


def find_bad_udim(obj, umin = 0, umax = 1, vmin = 0, vmax = 1):
    cmds.select(obj)
    cmds.polySelectConstraint( m =3, t=0x0010, d=1,dp=(0.5, 0.5, 0), db=(0, 0.7075))
    cmds.polySelectConstraint(disable=True)
    original_sel = cmds.ls(sl=True, fl=True)
    problems = []
    for component in original_sel:
    	u, v = cmds.polyEditUV(component, q=True, u=True, v=True )
    	if (u < umin) or (u > umax) or (v < vmin) or (v > vmax):
    		problems.append(component)
    return problems
    		
print find_bad_udim('pCube1')   

Theodox: Thanks for the reply. I manage to understand mostly of what you wrote. Unfortunately its not exactly what Im looking for. My code is suppose to be a inside the range test, for selecting uvs inside the uv tile.

It looks like your code is asking 'is this U inside (min, max) or is this V inside (min, max), which will select things that are valid in one or two dimensions.

Im not sure I understand this? Im still a newbie at coding, sorry.

The main function of the script is to select the uvs with in the User specified UDIM. for example user inputs 1003, it will select all the uvs within that UDIM tile. polyselectConstraint is to elminate the need to write a procedure to test every uv on the mesh which would be very slow. So i though that testing the selected uvs from the constraint selection would save some time.

here is the latest version of the code I wrote in mel. If you have a chance take a look at it, I would be grateful. reason that it is in mel is because its the only scripting language I know.
Im not sure how you append values to a array in mel. but heres what I did thats suppose to work. but instead it only select some uvs, no idea why its not working as intended.

global proc selectUDIMPatch(){ 
    polySelectConstraint -m 3 -t 0x0010 -d 1 -dp 0.5 0.5 0 -db 0 0.7075; // select uv covering the whole tile.
    resetPolySelectConstraint;
    string $ConstraintSel[] = `ls -sl -fl`; //store initial selection
    select -clear;
    int $minU = 0;
    int $minV = 0;
    int $maxU = 1;
    int $maxV = 1;
    string $finalUV[]; //variable for storing UV selection after testing
    int $numUVs = `size $ConstraintSel`;
    float $uvLoc[];
    float $Uarray[];
    float $Varray[];
    
    for($i = 0; $i < ($numUVs*2); $i++) { // *2 because uv location is store as pairs, odd number for u, even number for v
       $uvLoc = `polyEditUV -q -u -v $ConstraintSel`; //store u and v location for each uv in $ConstraintSel
       }
       
    for($j = 0; $j < $numUVs; $j++){ //store u into seperate array
       $Uarray[size($Uarray)] = $uvLoc[$j];
       $j++;
       }
       
    for($k = 1; $k < ($numUVs+1); $k++){ //store v into seperate array
       $Varray[size($Varray)] = $uvLoc[$k];
       $k++;
       }
       
    for($L = 0; $L < $numUVs; $L++){ //testing to see if uvs lies within the tile boundary then storing it
        if ($Uarray[$L] > $minU && $Uarray[$L] < $maxU && $Varray[$L] > $minV && $Varray[$L] < $maxV){
            $finalUV[size($finalUV)]= $ConstraintSel[$L];
        }
        
        else{
            continue;
        }
    }
    print $finalUV;
    select $finalUV;
    
}

selectUDIMPatch;


to store the right uvs. I cast it in a array “$finalUV[size($finalUV)]= $ConstraintSel[$L];” size($finalUV) acts as a counter using it to detemine the index of the array.

After many attempts, I manage to get the code to work. but not efficiently because It would freeze up maya when I have mesh that are in the 100k range.

After researching more about methods to acquire uv location. It seems that OpenMaya is the fastest at this. So I finally caved in and started diving into OpenMaya and Pymel.

Original code from https://www.mail-archive.com/[email protected]/msg06961.html

Heres my first attempt at OpenMaya, it just gets uv coordinates from selection mesh.


import maya.OpenMaya as om

def getuvsfromSel():
    selList = om.MSelectionList()
    om.MGlobal.getActiveSelectionList( selList )
    iter = om.MItSelectionList( selList, om.MFn.kMesh )
    dagPath = om.MDagPath()
    if iter:
        while not iter.isDone():
            iter.getDagPath( dagPath )
            meshFn = om.MFnMesh(dagPath)
            #Get UVSets for this mesh
            UVSets = []
            status = meshFn.getUVSetNames( UVSets )
            #Get all UVs for the first UV set.
            uArray = om.MFloatArray()
            vArray = om.MFloatArray()
            meshFn.getUVs( uArray, vArray, UVSets[0] )
            return [uArray,vArray]
            iter.next()

getuvsfromSel()

What I dont get is why it won’t return anything in the script editor using this return [uArray,vArray] It seems to only work if I use print ?