I spent today getting reacquainted with maya python though the digital tutors introduction to scripting in maya tutorial. I did quite a bit of this at the start of last year, but when I went to go back to it I found I had forgotten most of it. Considering that most fx artists jobs require at least one scripting language, I really need to get up to speed. The scripts I made today were not particularly useful, more just example projects to teach basic concepts.
Maya Commands, Concatenation and Lists
The first couple of exercises covered some basic concepts to get started in python. The first task was to create a script that generated a beveled cube, checking the mel commands by using the maya gui to produce them first. This was a nice easy start and things started coming back pretty quickly.
It started with producing this based on using a direct reference to the object being created, and then used a variable in place of the object name to make the script work more than once and be more generic.
The next task focused on string concatenation. The tutorial suggested using %d, %f and %hex for this, but I got errors every single time I tried to concatenate that way. Instead I used the str(“variable”) method we were taught last year. That did not work for the hexidecimal value, but considering I would work in RGB or HLS anyway, I do not think it is really a big deal right now.
The third task was lists and for loops. The aim was to populate a list with selected objects, then scale each object incrementally so that the each got bigger as you went along the list. Again, lists and for loops are something I have done before but it was nice to get a reminder of how basic logic works!
To scale incrementally, the loop was set up with 0 to the end of the list as the start and end values with the increment by one to get everything in the list. I defined a rescaler variable which took the current value(i) plus one and halfed it to get the amount to scale by. The plus one was there to avoid there being a 0 value.
The put all of the previous lessons together to create a script that could automatically generate a cog shape. To begin, I created the shape using maya tools. I created a pipe primitive, selected every second face, extruded and smoothed. Easy in the maya GUI, but I then needed to work out how to do this in script! Because it is possible to iterate by whatever number you please in a loop, getting every second face was not an issue, but getting only outside faces was. To do this, I selected the faces, got their numbers in the history in the script editor, and contrasted this to the number of subdivisions in the axis. After doing this for a couple of different subdivided pipes, I found out that the number of the first outside face is equal to the subdiv axis*2 and the the last one is the subdiv axis*3-1. I love that the tutorial included this bit of problem solving, as it is something I think I will have to do throughout the year, as I work out how effects can be optimised or used within gameplay.
Once this logic was worked out, I created it in python. Like in the other examples, I started off directly referencing the object that the script was being applied to. I used the getAttr command to create variables for the maths concerning the start and end faces then created a loop that iterated though the start face to the end face by two, selecting a face each time.
Smooth and extrude are simple commands, I just needed to work out how much I had extruded by previously. This then got me a cog!
Now that I could create a cog though the script, I needed to make it so that there was no direct referencing, allowing the script to be used multiple times. In order to do this, I had to create the polyPipe inside the script, give this creation a variable name and then use that instead of the direct reference in the loop.
The last thing to do was to create a window where the user could input what number of teeth they would like on the cog. I created a prompt dialogue that displays a message and is automatically set up to take a value. This was an introduction to if statements and querying. A variable and if statement was created that checked if the user had clicked OK so that the script knows when to run. I then queried the user’s input to the box, and if this was inputted correctly, converted it to an integer that can be used in the script. I then set the number of subdivisons of the pipe created to be equal to two times the number of teeth, as the teeth represent every second face.
The disperser script taught how to use additional modules with maya python. The idea was to move the cogs in the scene by a random number within a certain range. I created a list of all the objects currently selected, then iterated though the list by substituting the usual i in range for objects in my list. I then imported the random module and used the randint command from it to create variables that would be a random integer between the range that I specified. After that, I translated the objects by the variables.
I then needed to allow the user to specify the range of values. I created a window and some input boxes, something I was very familiar with as my technical art apps project last year had a lot of maya GUI work in it. In order to have the disperser script run when the button was pressed, I had to create a function, another thing I am being reintroduced to! I was really glad to get to this point, as functions really make things much neater and easier to deal with. In order to take the values that the user inputs and get them into the script, I created variables that queried each value in the float field group. I then used these variables, along with a minus version of them, to create the range for the random integer to translate by.
This task was designed to show how expressions and scripts can work together to create tools that work on the timeline. I started of by creating a script that made one object copy the animation of another. I found the first and last frames by querying the playbackOptions command and then set one object to be a goal, and another to be the follower. The goal object had some really simple animation applied to it. I then used these in a while statement, which is something that is done continuously as long as the specified conditions are met. In this case, as long as the current frame was smaller than the end frame (aka, the animation was being played) the script would run. I took the translate value from the goal, stored as a tuple, and set the keyframes of the follower object to this.
I then made this more efficient, taking out the need to check the frames by using the expression editor. Expressions are called every frame automatically. I put the current code into a function and took out the goal and follower variables, asking for them to be returned in the function instead. I also asked for the amount of lag in the function. The lag was then used in the time flag with the setAttr command, which was surprisingly easy!
The last thing I did was make multiple swords with materials with various levels of transparency, to create a sort of motion blur looking effect. This looked really cool and showed the potential of scripts like this to be used to create fx – this would be a really nice sword slashing fx in a game. (Of course multiple meshes and materials would probably not be an option for real time!!!)
I feel like a lot of this has come back to me now, which is great. Hopefully if I continue to work on my scripting skills a little each week, I can be at a good level when I graduate. I would like to create more practical examples in the future, hopefully I can make some scripts that will help my pipeline when using maya.
Digital Tutors. 2009. Python Scripting in Maya. [online]. Available from:
[Accessed 1 October 2014].