maya paintFX leaf UV layout script

david | mentalray,python,rendering,vray | Thursday, March 10th, 2011

Update 2012-07-28: The script has been updated with new features, which include a user interface replacing the command-line stuff. The leaf layout details explained here are still relevant and correct, except for the command to run the script. The new command can be found at the end of the new post.

There is a long, long thread on cgTalk called "Forests in maya mental ray".  The discussion is all about techniques for creating and rendering the vast numbers of polygons needed to make convincing grass and trees in large numbers.

Maya's paintFX can be used to make trees which can be converted to polygons with leaves that consist of just a few polys per leaf. Texture maps (color, opacity, bump etc) are then applied. The default output from the paintFX conversion has each leaf mapped to fill the standard uv quadrant, so each leaf gets a copy of the texture. This can look pretty good, but the repetition is usually very obvious. You could break the leaf mesh into a few parts and assign variations of the leaf textures to each part. But a more efficient way is to layout the uv's so that groups of leaves are mapped to different parts of the uv quadrant in a 4x4 tiled patternfor example. Then you can make a texture map with leaf variations arranged in the same 4x4 tile pattern. Now you can have 16 different looking leaves on the tree, almost as easily as you can have one.

Default paintFX conversion gives you this


But what you really want is something like this 4x4 tile pattern (or maybe 2x2 or 3x3)


The problem is that you might have 50,000 leaves on your tree. It would be very difficult to select and edit the uv's for different leaves by hand. This is something that needs to be automatedAround page 12 of the Forests thread Roberto Fdez. de Gamboa (aka tostao_wayne) posted a mel script that was able to loop through the leaves and edit each one to fit in one of the randomly selected tiles. It got the job done, but could easily take over an hour to process, depending on the number of leaves.

I've recently been teaching myself to write python scripts so I decided to see if I could rewrite Roberto's script in a way that would cut down on processing. I knew this would mean leveraging the power of the maya API so as well as reading the manual I looked around for code examples to learn from.

As luck would have it, I discovered a recent post at Maya Station by Owen Burgess that showed how to extract information about uv shells from a poly mesh. This was a big head start, and after some study I wrote can process 50,000 leaves in approx 30 seconds on my old quad core. It arranges leaves into 2x2, 3x3 or 4x4 tiles. You can select multiple meshes to process one after the other.

Install it by placing in your local scripts folder.

Run it by first selecting a poly mesh. Then execute the following command in a python tab in the maya script editor window.

import djPFXUVs; djPFXUVs.leafLayout(3)

You can change the number in the parentheses to 2, 3 or 4 to get 2x2, 3x3 or 4x4 tiles. And you might want to drag the code to your shelf for future use.

The script seems pretty robust, but I would recommend saving your scene prior to running it - just in case. The script runs with undo turned off, so you will not be able to go back.

Get from my downloads page.

UPDATE 15 March 2011:

A few script limitations that have been brought to my attention.

  • No multiple uv set support. Script only operates on the uv's in map1 (the default uv set).
  • Meshes with history may revert to old uv's after script finishes.
  • Very little error checking is performed

When I get some more time I'll address some of these issues, but for now you'll just have to live with them.

UPDATE 28 July 2012:

User interface and grass layout and multiple uv-set support added. New command to load the ui.


  1. I've just been notified that there was a space in the name of the python file, just before the period. I've fixed it in the rar, but if you've already downloaded the file, then you need to rename "djPFXUVs .py" to "".

    Comment by david — March 12, 2011 @ 10:52 am

  2. Been here before (you helped me out with something a while back) and I just wanted to say I love your site. I am currently wading through that very same thread on CG Talk as I am hoping to create a PFX forest of my own. I am planning on testing out your script once I get my head wrapped around everything in that thread. I Keep stalling, hoping someone condenses the workflow into a tutorial with some commentary I can follow (not a lot of free time right now). Will post back when I have something to show - much appreciated.


    Comment by nbreslow — March 15, 2011 @ 2:42 am

  3. Thank you for sharing your script, David! I'll give it a try as soon as I have a chance.
    That thread on CGTalk is certainly a treasure.

    Comment by AndreiSE — March 17, 2011 @ 1:36 pm

  4. Hi David,

    Might I mention 2 other methods for this...

    You might use a tripleSwitch for texture assignment on converted Geo leaves. You'd have to write a quick assignment/randomize script to make kife manageable, but I think it would be a lot faster than scripting a UV edit. We made a script for that a while back. I can try to dig it up if you want.

    Or. We also made a script to create a particle with proper direction at each leaf base. Then used a particle instancer to place random geo. we used that when we needed complex geo to replace leaves on a tree for a hero Pine tree with snow.

    Comment by aweidenhammer — March 23, 2011 @ 8:35 am

  5. Nice of you to drop by Andrew. I've tried the tripleSwitch before (also a variant using a singleSwitch). I've found it to be too slow with large numbers of geometry. I'd like to check out your script though so I can compare. I've looked at particle placing and instancing too.

    I think that the script I've just written is best suited to the particular case where you have a single mesh consisting of thousands of leaves, usually created by converting a paintFX tree to polys. The script is able to very quickly layout the uvs into tiles. After that I can assign shaders and a single file texture can contain all the leaf variations (usually alpha mapped onto the simple rectangular leaf geo). I'll post an update shortly where you can create a 2nd uv set that allows a 2nd color variation texture to be assigned as a multiplier or gain/offset. This combined with the leaf shape texture creates the posibility for 100's of leaf variations very easily and efficiently, especially if you then convert to a vray proxy.

    Comment by david — March 23, 2011 @ 7:38 pm

  6. I can't seem to find that script. I even remember the project we wrote it for, and it's not there. Sorry. I'm sure it was a very simple iteration of selected items piping into the tripleSwitch. I'm honestly not aware of how it would hold up across a LOT of leaves. You may very well have the faster method. Every scene does call for its own best solution. Since you seem to have already at least explored the options I mentioned, you probably do have the best thing going for your scene. I'll be making a note of this post for when it comes time for me to render massive numbers of trees.

    Comment by aweidenhammer — March 24, 2011 @ 5:48 am

  7. hi thare
    got this massege: // Error: ''' //
    // Error: Syntax error // . when trying to load the script
    what to do?

    Comment by gofer — December 11, 2013 @ 12:07 am

  8. That is not much for me to go on, but I'll take a guess that you are trying to launch the script the wrong way. This link contains instructions on how to run the current version of the script.
    Have a look there and see if that helps. Make sure you have the latest version of the script too.


    Comment by david — December 11, 2013 @ 12:20 am

  9. thanks
    work perfect , but.. it's does't gave me any separate from each uv to the ather, shuld i use the "tile separation" mode?


    Comment by gofer — December 11, 2013 @ 8:05 pm

  10. Yep "tile separation" should do it.

    Comment by david — December 11, 2013 @ 10:55 pm

  11. Hi, david. I've been using your script for a long time and it really helps me in different situations. But now I have faced some difficulties because of one sadly limitation of your script. The goal is: I need to save my pfx history on my converted to poly pfx. And when I use the script it works fine so far I close/open my scene, or change my leaf width or curl, or anything else. For plants with the small count of leaves(polygons) I cheated like this: I have exported my leaves to the UVLayout with bridge that ships with the program and after that just send it back. As a result I have "polyTransfer" node in my histiory that give me the opportunity to close/open, change some of the parameters in my pfx and there is no need to run your script every time I make a changes.
    But with heavier geometry UVLayout doesn't work. It import geo infinitely long.
    I can, of course, duplicate my leaves and transfer new uv's to original leaves and there will be polyTransfer history node, but there will be duplicated geo too and it's not the way to work...
    So... If you have a time, may be you can implement some history node, that will keep uv's after the script's work?
    Thank you anyway!

    Comment by Fomen — December 15, 2013 @ 9:18 pm

  12. So it sounds like you want my PFXUVs script to be converted into a plugin that would enable it to run as a node instead. This is an interesting idea. It might work, but my guess is that even, as a c++ node, it would still be very slow for dense meshes. I use a camera projection plugin that does very simple manipulation of uv's and it is slow for dense meshes.

    Anyway, right now I do not have time to even attempt this. But I might give it a try in the next few months. I would probably start by writing it as a python node and see how it looks. If I get that far I'll let you know.


    Comment by david — December 21, 2013 @ 11:10 pm

  13. Thanks, david. I'll wait for any news.

    Comment by Fomen — December 23, 2013 @ 3:25 pm

  14. Hello, I'm Candance, from a NPO and want know that all the script for maya on your website can be free used in our works? We will use it for make some materials in our videos and put these videos on YouTube for non-commercial purposes. Out of the respect of your work and in order to avoid some misunderstanding, we’d like you to confirm that you hold the copyright of these script and agree us to feel free to use them.


    My Email:

    Comment by candance000 — April 13, 2016 @ 5:18 pm

RSS feed for comments on this post.

Leave a comment

You must be logged in to post a comment.

Powered by WordPress | Based on a theme by Roy Tanck