Saturday, April 02, 2011

Cleanly transferring UV's to a skinned model

Why does the transfer attributes node sometimes resist getting deleted on a rigged model? Doesn't it know resistance is futile?
I've had it happen many times that a UV set has to get transferred onto a skinned model via transfer attributes operation. And then refuses to go away. Which sucks cuz cleaner history is better. This a quick vid about why that happens and how to kill that history. Thanks to Christina Sidoti for pointing it out to me!

Edit: Oh yeah . . . Here's a script to help you do it faster! Download it HERE (rt-click, save). Put it in your scripts directory, start Maya (or type "rehash" in the MEL command line if it's already open). Select the obj with the new UV's, then the rigged object with the old UV's and type "zbw_cleanTransferUV". (catchy name, right?). It seems to work fine for anything I've tried it with. If you've already got some UV changing history (polyTweakUV or transfer UVs, etc) you can delete those, you're new UVs are coming straight from the source and any previous tweaks will get weird.

Carry on!

Maya/Rigging: Cleanly Transferring UVs to a Bound Rig from zeth willie on Vimeo.


  1. On the subject of cleaning up your project, I have a question for you.

    Occasionally, I'll delete a mesh (named meshImport, for example), then long after that, I'll import that same mesh into a project, or rename an existing mesh the same name. Maya will then append a 1 to the end of that name (or, a 2 or 3 sometimes).

    I assume there's some internal gunk that makes Maya think that there are duplicate meshes. Is there any way to address this?


  2. Maya does get a bit weird about naming stuff (would be worse if it didn't, though)
    You've got namespace issues when you import/reference things. But you also have hierarchy space stuff. So you can have 2 spheres, each in their own group, both name "sphere1". No problem, because their actual name is "group_whatever|sphere1", not "sphere1". But if you create a new sphere it'll get "sphere2" even though it's not in hierarchy space. You can THEN rename it back to sphere1, so you have 3 "sphere1" objects (this is important when scripting, because you'll have to pull the REAL name with all the "|" symbols, not the "sphere1".
    Also, if you go to the outliner and check off the DAG only option, you'll see that there all types of other nodes that can confuse the naming. Shaders, character sets, deformer bits, hidden nodes, etc can all mess up your naming. So it's important to do two things: make sure you name well (sphere1_shd for the shader, for ex) and that you really clean up your scene when import/delete, etc. Sometimes conflicts are unavoidable, but you'll have less of them if you're careful.
    That help?


  3. Thanks a lot for this script!!!

  4. No worries Tobi. Just a word of warning.I did have some issues in production when an object gets passed through a bunch of references and for whatever reason, the "orig node" is no longer named correctly. Not even sure when/how it happened, but since the script is looking for the "orig" shape, it may not work correctly in certain circumstances :p

  5. Zeth! Thanks a bunch, great tutorial!

  6. hey man, very usefull script.
    thanks a lot

  7. Much needed script! Thanks!

    I'm getting the error "Cannot convert data of type int[] to type float" whenever I try to use. Any ideas?

    I am using Maya 2012.


  8. @Teezy-

    I'll look into it when I have a moment . . .

  9. Zeth, thank you so much for this helpful script and video! You're a lifesaver!

    It worked well for most of the meshes in my scene, but I did get the same error as teezy5 for a couple of them, and I think I found a solution. The error was thrown from:

    `getAttr ($targetOrig+".intermediateObject")`;

    The problem in my case was that there was more than one object named '$targetOrig' in my scene, and thus the return value of the 'getAttr' was an int[] containing the intermediateObject values for all matching objects, instead of just an int. In order to only get the unique intermediateObject for the selected geometry, 'listRelatives' needs to return the full dagpath. Basically, I just changed the line:

    string $targetShapes[] = `listRelatives-s $target`;


    string $targetShapes[] = `listRelatives-s -f $target`;

    And it worked. That's it! Thank you again!

  10. Hey,

    I haven't tried the script yet, have been trying to do it manually first but my problem is that the 'original shape' isn't an 'intermediate object' and when I tried the tutorial it just acted exactly the same as the regular mesh did with the same problems.

    I haven't touched that object in all my rigging so I couldn't have unchecked the intermediate object box earlier.

    If I check the box now then it affects the skinned mesh node too.

    Does anyone have any idea why this might be and how I could get around it?

    Any help would be very much appreciated

    Thanks :]

  11. Zeth,

    Great blog! You have created an awesome resource. Thank you very much.
    I was able to successfully transfer updated UVs to a mesh that I had already rigged and it looked like it had worked until I went to apply the texture to the model.

    Can you check out this link and tell me if you've seen anything like it? It almost looks like the texture is being rotated within each face. Is there any way to fix this?