[Python] Script seemingly not returning UV IDs correctly

[Python] Script seemingly not returning UV IDs correctly

Anonymous
Not applicable
1,067 Views
2 Replies
Message 1 of 3

[Python] Script seemingly not returning UV IDs correctly

Anonymous
Not applicable

Hi all,

 

This is a difficult one to explain and I think that it probably arises from my lack of knowledge of how UVs actually work.

 

I've written a script that aligns a UV shell orthogonal to a selected edge, however it only seems to work when I select certain edges. When it doesn't work it's because the selected edge will only convert to one UV point (ID?) when I call polyListComponentConversion(). What I want to know is why some edges that I select will convert to two UVs, and some will only convert to one. It seems like border edges happily convert to two UVs.

 

For instance, selecting this edge, between UV points 88 and 99 will return an error, because the conversion will only return one UV ID.

 

8899.PNG

 

However, selecting this edge will work fine, and I can't understand why.

 

25.PNG

 

As far as I can see, both of these edges are connected to two UV points, so would one work and the other not?

 

Thanks!

 

Code is attached in full below.

 

'''
Created on 18 Jul 2016

@author: BenjiA

About:
This tool attempts to rotate a UV shell so that it is oriented 90 degrees orthogonal to the edge that you select

Use:
Select an edge and run the tool, if you get a list index out of range error, try another edge
'''
import pymel.core as pm;
import maya.api.OpenMaya as om;

def GetSel():
    #Get the selected edge
    sel = pm.selected();
    if not sel:
        raise RuntimeError('Select an edge or a face, and run the tool again');
    else:
        selType = pm.nodeType(sel);
        #make sure its an edge by converting it to an edge
        selEdge = pm.polyListComponentConversion(te=1);
        return selEdge[0];

def GetVectorsAndRotate(sel):
    #convert the edge selection to uvs
    selUVs = pm.polyListComponentConversion(tuv=1);
    if len(selUVs) < 2:
        print 'selUvs length is ' + str(len(selUVs));
        raise RuntimeError('Select a face or an edge with more connected UV point');
    else:
        print 'selUvs length is ' + str(len(selUVs));
        #get the two UV points individually
        UV0 = pm.polyEditUV(selUVs[0], query=1, u=1, v=1);
        UV1 = pm.polyEditUV(selUVs[1], query=1, u=1, v=1);
        #work out the vector that represents the edge between the UV points
        edgeVect = pm.datatypes.Vector((UV0[0] - UV1[0]), (UV0[1] - UV1[1]));
        #normalize it
        edgeVect = edgeVect.normal();
        print 'Edge vector is:', edgeVect;
        #get the vector orthogonal to the edge vector
        orthVect = pm.datatypes.Vector(-edgeVect[1], edgeVect[0]);
        #normalize it
        orthVect = orthVect.normal();
        print 'Perpendicular vector is:', orthVect;
        #calculate the arctangent of the orthogonal vector
        atan = pm.datatypes.atan2(orthVect[1], orthVect[0]);
        print 'Arctangent is:', atan;
        #convert the arctangent to degrees
        degrees = pm.datatypes.degrees(atan);
        print 'Atan to degree conversion is:', degrees;
        #get the parent object of the selected uv points
        selObj = pm.PyNode(sel, s=1);
        selObj = selObj.split(".");
        selParent = pm.PyNode(selObj[0]).getParent();
        #select the whole shell
        selFaces = pm.polySelect(ets=1);
        #rotate the shell by the calculated degrees
        pm.polyEditUV(a=-degrees, pu=0.5, pv=0.5);
    
GetVectorsAndRotate(GetSel());
0 Likes
Accepted solutions (1)
1,068 Views
2 Replies
Replies (2)
Message 2 of 3

RFlannery1
Collaborator
Collaborator
Accepted solution

My guess is that the edge you picked has consecutive UV IDs.  If the UVs are consecutive, they will be returned as a single item.  For example, [u'myMesh.map[14:15]'].  You can use the "ls" command to separate out the results into individual components.

from maya import cmds
# Skipping a bunch of lines here

selUVs = pm.polyListComponentConversion(tuv=1) selUVs = cmds.ls(selUVs, flatten=True)
Message 3 of 3

Anonymous
Not applicable
Thanks buddy, that solved the issue - I didn't even know about flatten, thanks very much 🙂
0 Likes