Question

I'm wondering if there is a way to perform the following, I'm aware that to set say the translation of an object, in pymel it's as simple as this:

object.translateX.set(1.5)

and you can also set this using the 'setAttr' command:

setAttr(object + '.translateX', 1.5) or setAttr('%s.translateX' % object, 1.5)

However, what If I only wanted to use the first example with something a little more advanced where the attribute name would change?

Example:

object.translateX.set(1.5)
object.translateY.set(1.5)
object.translateZ.set(1.5)
object.rotateX.set(1.5)
object.rotateY.set(1.5)
object.rotateZ.set(1.5)

I'd much rather write something like this:

for i in range(0,5,1):
    t = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ']
    object.t[i].set(1.5)

However this obviously doesn't work, but can someone tell me if there's a way to do this?

Was it helpful?

Solution

Now, I do not know pymel or anything related to Maya, but if object.translateX.set(1.5) works, then I think the access works like normal object attribute access, so you can get an attribute by name using the getattr(object, attrname[, default_value]).

BTW range(0, 5, 1) is the same as range(5); and means a list [ 0, 1, 2, 3, 4 ]; your list has 6 elements so you'd need range(6) to iterate over it - but as for loop can iterate over any iterable, you should just iterate over your attribute names. Thus:

attributes = ['translateX', 'translateY', 'translateZ', 
              'rotateX', 'rotateY', 'rotateZ']
for a in attributes:
    getattr(object, a).set(1.5)

should do what you wanted.

Update: pymel seems to also support .attr() for objects, thus

for a in attributes:
    object.attr(a).set(1.5)

OTHER TIPS

The pymel method looks like this:

for item in ['translateX', 'translateY', 'translateZ']:
   myObject.attr(item).set(0)

As an addendum to theodox's answer, using PyMEL you can also write:

object.t.set([1.0, 1.0, 1.0])
object.r.set([180.0, 360.0, 90.0])

to summarise

import pymel.core as pmc
cube= pmc.polyCube()

attributes = ['tx', 'ty', 'tz', 
              'rx', 'ry', 'rz']

for a in attributes:
    cube[0].attr(a).set(1.5)

or

cube[0].t.set([1.5]*3)
cube[0].r.set([1.5]*3)

If it is possible to filter your transform nodes with a single wildcard (*) then you can get Attribute-objects to directly set them as follows:

import pymel.core as pm
for tX in pm.ls('spine*_jnt.translateX'):
    tX.set(0.0)

As you can see 'ls' function can list attributes too but cannot accept complex regex patterns. This way you can also flag nodes in your scene with an identifying attribute and can collect them with listing as seen here. You can set vectors in one pass if needed:

import random as rnd
for t in pm.ls('treeA_*.translate'):
    t.set([rnd.uniform(-20,20), 0.0, rnd.uniform(-20,20)])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top