This post is intended as a follow-up to: Getting objects inside a script
If you've been using Python in Maya for long you're probably already used to typing this at the beginning of every script:
import maya.cmds as mc
Maybe you assign it to a different name, like cmds or commands or something. In any case, Cmds is great - it's just outdated is all. It has a newer, sleeker sibling called Pymel.
Autodesk's own website describes Pymel as being what Cmds was always meant to be. As the name implies, it is a more successful fusion of Python and MEL.
The great thing about switching to Pymel is that you barely need to learn anything new. All you need to do is import pymel.core at the top of each script instead of maya.cmds.
No more of this:
import maya.cmds as mc
Instead, this!:
import pymel.core as pm
All the functions that Cmds gives you access to, Pymel has as well.
selecting something in Cmds looked like this:
mc.select("|pCube1")
it's exactly the same in Pymel:
pm.select("|pCube1")
There are a couple of adjustments to some of the parameters in a few functions here and there. Like... two whole examples come to my mind. So 99.9% of the time, it's the same as in Cmds.
That means aaaaaaaall the outdated tutorials that teach you stuff using Cmds - that's all still good info, just put pm in front of the functions instead of mc and you're all caught up.
At this point you might be wondering "If pymel is the same as cmds, what even is the benefit of making the switch?"
You ask the right questions! Well done, you.
While the things you type don't need to change when making the switch, Pymel has one major feature that will make your scripting life a hell of a lot easier:
Pymel can store Maya objects in variables.
This might be a little tricky to understand at first. Using Cmds, python doesn't actually store a Maya object as a variable.
If I have a cube called "|pCube1" and I type and execute:
cube = "|pCube1"
The cube object itself is not what's stored inside the variable. The variable only contains the object's name as a string.
Maya is usually smart enough know when we attempt to manipulate that string that we actually want to manipulate the object whose name matches that string.
But as we've seen here -
Don't Use Cmds - Use Pymel
- trying to keep track of objects based on what those objects' names are is playing with fire. Because those objects will change their name all the time, such as every single time it's reparented.
Here i'll assign an object's name to a variable, then change that object's name, and then attempt to select the object using that variable:
loc = "|locator1"
mc.rename(loc, "updatedLocator")
mc.select(loc)
As you can see, as soon as the name of the object changes, the name stored in the variable no longer refers to the correct object. In this case, the variable now refers to an object that doesn't even exist, hence the error.
Pymel, however, works a little more intuitively.
Let's import pymel at the top of our script:
import pymel.core as pm
Using pymel, you can store the object itself in a variable. To do this, you'll make extensive use of the ls command that was available in cmds and so is also available in pymel.
You cannot simply do this:
loc = "|locator1"
This would just assign a string to the loc variable, which is what we're trying to avoid.
Instead try this:
loc = pm.ls("|locator1")[0]
(I'll explain that [0] on the end in just a moment)
Now the locator object itself is what's stored in the variable. That means you can do stuff to it using functions, just like Cmds:
pm.parent(loc, group1)
We've reparented the locator! You know what that means! Its path is different! "|locator" is out of date,
but... we never assigned the string "|locator" to the loc variable >: )
No, we assigned the object "|locator" to the loc variable.
THAT MEANS... the variable keeps track of that object, even if its name changes:
pm.parent(loc, sphere1)
If this seems like magic, let me explain:
When you use Pymel, and you assign an object in the scene to a variable, what's assigned to that variable is not the object's name, but its address in the computer's memory. An object's memory address is way more stable than its name. You can do all sorts of the things to an object so it's not the same as it was before, but nothing short of closing and reopening Maya, or deleting an object and rebuilding it from scratch will alter an object's memory address.
So once you've assign an object to a variable, that variable remains up to date all throughout your script. It's plainly superior than trying to keep track of an object by always being conscious of what the object is called and where it is in the hierarchy at given moment.
So do yourself a favour. Don't use Cmds. Use the more up-to-date Pymel.
Oh by the way... that's far from the only advantage to using Pymel >: )
And as promised, let's take a closer look at that ls command, and what the deal is with that ugly [0] on the end: The ls() Command
No comments:
Post a Comment