MEL How-To #72

Back · Previous · Next Maya

How do I output the UVs for each Vertex component?

Maya maintains a mapping for each vertex to an entry in the object's UV table (this table is part of the mesh node). This way, UVs can be optimized for reuse when possible.

Use the ‘polyListComponentConversion’ command to convert each Vertex component to its corresponding UV mapping:

select -r pCube1.vtx[3];

polyListComponentConversion -fv -tuv;
// Result: pCube1.map[3] //

You can then use the ‘polyEditUV’ command to query the UV value:

polyEditUV -q pCube1.map[3];
// Result: 1 1 //

Each vertex has the potential to be mapped to 'n' UVs, where 'n' is the number of faces using that vertex. For example, a vertex is assigned to multiple UV mappings when the "Cut UVs" function is applied to its Edge component. To obtain a 1:1 vertex-to-UV relationship in this case you must query per-vertex per-face UVs. Maya maintains these as ".vtxFace" components.

The first step is to determine how may faces share the given vertex:

select -r pCube1.vtx[0];
polyListComponentConversion -fv -tf;
// Result: pCube1.f[0] pCube1.f[3] pCube1.f[5] //

This tells you that .vtx[0] is shared by faces 0, 3 and 5.

Now build three queries, one for each face:

// Declare a string for the result.
string $uvMap;

// Query Vertex 0 for Face 0
select -r pCube1.vtxFace[0][0];
$uvMap = `polyListComponentConversion -fvf -tuv`;
// Result: pCube1.map[0] //
// Query the UV for this mapping.
polyEditUV -q $uvMap;
// Result: 0 0 //

// Query Vertex 0 for Face 3
select -r pCube1.vtxFace[0][3];
$uvMap = `polyListComponentConversion -fvf -tuv`;
// Result: pCube1.map[8] //
// Query the UV for this mapping.
polyEditUV -q $uvMap;
// Result: 0 4 //

// Query Vertex 0 for Face 5
select -r pCube1.vtxFace[0][5];
$uvMap = `polyListComponentConversion -fvf -tuv`;
// Result: pCube1.map[0] //
// Query the UV for this mapping.
polyEditUV -q $uvMap;
// Result: 0 0 //

To build the ".vtxFace" component indices you'll need to extract the component index from the vertex and from each face in the array returned when using ‘polyListComponentConversion’ to obtain the face list. Here's a MEL procedure I use to extract component indices from a string:

// //////////////////////////////////////////////////////////////////////
//  componentRange
//
// Description: Parses the provided selection item (presumably with a
//  component factor (e.g. "pSphere.vtx[0:25]") and returns the
//  start and end for the selection range.
//
// Example: If vertices 3 through 5 of a model are selected, Maya
//  lists this as 'polyModel.vtx[3:5]'; in this case, componentRange()
//  will return the array { 3, 5 }.  If only a single vertex is selected,
//  Maya lists this as, e.g., 'polyMode.vtx[12]'; in this case,
//  componentRange() will return the array { 12, 12 }.

proc int[] componentRange( string $select )
{
  string $buffer[];
  int $i, $tokens;
  int $elements[2] = { 0, 0 };

  $tokens = `tokenize $select "[:]" $buffer`;

  $elements[0] = $elements[1] = int($buffer[1]);

  if ( $tokens > 2 )
    $elements[1] = int($buffer[2]);

  return $elements;
}

Related How-To's

Tuesday, October 09, 2001