Установить атрибут без объединения строк

Мне интересно, есть ли способ выполнить следующее, я знаю, что, чтобы установить перевод объекта, в pymel это так же просто:

object.translateX.set(1.5)

и вы также можете установить это с помощью команды setAttr:

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

Однако что, если бы я хотел использовать первый пример только с чем-то более продвинутым, где имя атрибута изменилось бы?

Пример:

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)

Я бы предпочел написать что-то вроде этого:

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

Однако это, очевидно, не работает, но может ли кто-нибудь сказать мне, есть ли способ сделать это?


person Shannon Hochkins    schedule 22.08.2013    source источник


Ответы (5)


Теперь я не знаю pymel или что-либо, связанное с Maya, но если object.translateX.set(1.5) работает, то я думаю, что доступ работает как обычный доступ к атрибутам объекта, поэтому вы можете получить атрибут по имени, используя getattr(object, attrname[, default_value]).

Кстати, range(0, 5, 1) такое же, как range(5); и означает список [0, 1, 2, 3, 4]; в вашем списке 6 элементов, поэтому вам понадобится range(6) для его повторения, но поскольку цикл for может выполнять итерацию по любому итерируемому объекту, вам следует просто перебирать имена атрибутов. Таким образом:

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

должен сделать то, что вы хотели.

Обновление: pymel, похоже, также поддерживает .attr() для объектов, поэтому

for a in attributes:
    object.attr(a).set(1.5)
person Antti Haapala    schedule 22.08.2013
comment
ах, pymel, кажется, также поддерживает attr() - person Antti Haapala; 22.08.2013
comment
Помните, как вы сказали, что не знаете pymel? лол, это заглавная А в pyMel - person Shannon Hochkins; 22.08.2013
comment
Изменение getAttr на attr тоже не сработало, однако сработало использование getAttr :/ - person Shannon Hochkins; 22.08.2013

Метод pymel выглядит следующим образом:

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

В качестве дополнения к ответу теодокса, используя PyMEL, вы также можете написать:

object.t.set([1.0, 1.0, 1.0])
object.r.set([180.0, 360.0, 90.0])
person Argiri Kotsaris    schedule 22.08.2013
comment
круто!, где вы взяли эту ссылку? Фактический атрибут, который я устанавливаю, на самом деле называется offsetTranslateX, поэтому будет ли работать object.offsetTranslate.set([1,2,3])? - person Shannon Hochkins; 23.08.2013
comment
Да действительно было бы. В зависимости от типа объекта вы можете запустить object.listAttr(), чтобы получить список атрибутов. Просто запустите dir(object), чтобы увидеть, есть ли у него метод listAttr() или нет. В PyMEL это атрибут 3 type, означающий, что вы можете передать ему кортеж или список с 3 значениями. Вы можете проверить, принимает ли атрибут несколько значений, запустив object.attr.isMulti(). - person Argiri Kotsaris; 23.08.2013
comment
Вау, я ничего этого не знал! Спасибо! - person Shannon Hochkins; 23.08.2013

чтобы обобщить

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)
person Johan Flod    schedule 27.03.2016

Если возможно отфильтровать ваши узлы преобразования с помощью одного подстановочного знака (*), вы можете получить объекты-атрибуты, чтобы напрямую установить их следующим образом:

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

Как видите, функция 'ls' тоже может перечислять атрибуты, но не может принимать сложные шаблоны регулярных выражений. Таким образом, вы также можете помечать узлы в своей сцене с помощью идентифицирующего атрибута и собирать их с помощью списка, как показано здесь. При необходимости вы можете установить векторы за один проход:

import random as rnd
for t in pm.ls('treeA_*.translate'):
    t.set([rnd.uniform(-20,20), 0.0, rnd.uniform(-20,20)])
person Mathcom    schedule 01.09.2016
comment
добавить больше пояснений - person Kaleem Ullah; 01.09.2016