如何在 PyMEL 中访问属性?
How are attributes accessed in PyMEL?
有多种方法可以访问 PyNode
的属性,例如 Transform
,它具有 translation
、rotation
等属性。
import pymel.core as pm
cube = pm.polyCube()[0]
cube.translationX.set(1)
cube.translation.translationX.set(2)
cube.tx.set(3)
cube.t.tx.set(4)
# and more
我不明白这些属性是如何找到的,因为我找不到任何列出属性的文档? Transform
是否具有所有这些属性,其中每个属性都指向 DAG 节点的相应基础属性?映射发生在哪里以便找到正确的属性?
您可以只使用:
cube.listAttr()
我不确定他们是否包装了所有属性。
我自己有一个简单的 cmds 包装器,我只是通过覆盖动态添加节点的任何属性:getitem、getattr
这是 git 上的完整代码:https://github.com/DrWeeny/Whosebug/blob/master/59185039.py
这只是一个例子
class MAttr(object):
"""Represent a maya attribute
Args:
node (str): a string for the maya node affected
attr (str): a string that represent the attribute
Attributes:
attr_bypass (str): regex to bypass the compound attributes, because i need to connect and getattr
"""
attr_bypass = re.compile('\[(\d+)?:(\d+)?\]')
def __init__(self, node, attr='result'):
self.__dict__['node'] = node #: str: current priority node evaluated
self.__dict__['attribute'] = attr #: str: current priority node evaluated
self.__dict__['idx'] = 0 #: str: current priority node evaluated
def __getitem__(self, item):
"""
getitem has been overrided so you can select the compound attributes
``mn = MayaNode('cluster1')``
``mn.node.weightList[0]``
``mn.node.weightList[1].weights[0:100]``
Notes:
the notations with list[0:0:0] is class slice whereas list[0] is just and int
Args:
item (Any): should be slice class or an int
Returns:
cls : MAttr is updated with the chosen index/slice
"""
if isinstance(item, int):
self.__dict__['attribute'] = '{}[{}]'.format(self.attr, item)
else:
if not item.start and not item.stop and not item.step:
item = ':'
else:
item = ':'.join([str(i) for i in [item.start, item.stop, item.step] if i != None])
self.__dict__['attribute'] = '{}[{}]'.format(self.attr, item)
return self
def __getattr__(self, attr):
"""
__getattr__ is overriden in order to select attributes
Args:
attr (str): name of the attribute, even if we loop throught,
Returns:
str: it join all the attributes that has been chained : weightList[0].weight
"""
myattr = '{}.{}'.format(self.attr, attr)
if myattr in self.listAttr(myattr):
return MAttr(self._node, '{}.{}'.format(self.attr, attr))
else:
return self.__getattribute__(attr)
class MayaNode(object):
"""Represent a maya node as a class like pymel
Only provide the name as a string, if you use preset, you can create a new node
Note:
Should use maya api for getting the node
Args:
name (str): a string for the maya node you want to encapsulate
preset (:obj:`dict`, optional): Used for creating a new node from 'attrPreset'
you can also just specify the nodeType with a string instead
Attributes:
maya_attr_name (maya_data): Any attribute from the name will look for actual maya attribute
"""
def __init__(self, name, preset={}, blendValue=1):
# this dict method is used to avoid calling __getattr__
self.__dict__['node'] = name #: str: current priority node evaluated
self.__dict__['item'] = 1 #: int: can be either 0 or 1 and should be exented with Mesh or Cluster
if preset:
targ_ns = name.rsplit(':', 1)[0]
self.loadNode(preset, blendValue, targ_ns)
def __getitem__(self, item):
"""
getitem has been overrided so you can select the main nodes sh or tr so when you do:
``mn = MayaNode('pCube1')``
``mn[0].node`` result as the transform
``mn[1].node`` result as the shape
Note:
By default ``mn.node`` is the transform
"""
return self.setNode(item)
def __getattr__(self, attr):
"""
getattr has been overrided so you can select maya attributes and set them
if you type an attribute, it will try to find if it exists in either shape or transform
if it exists in both, it will always warn you that it returns shape in priority
``mn = MayaNode('pCube1')``
``mn.translateX = 10`` result in doing a cmds.setAttr
``mn.translateX.set(10)``
``mn.translateX.get()`` note that you to use get in order to do getAttr otherwise it __repr__ or __str__
``mn = MayaNode('cluster1')``
``mn.weightList[1].weights.get()`` is equivalent of cmds.getAttr('cluster1.weightList[1].weights[:]')
Note:
You cant have the value without .get()
"""
if attr in self.listAttr(attr):
return MAttr(self.node, attr)
elif attr in self.__dict__:
return self.__dict__[attr]
else:
try:
return self.__getattribute__(attr)
except AttributeError:
cmds.warning('{} doesn\'t exists, return None instead')
return None
有多种方法可以访问 PyNode
的属性,例如 Transform
,它具有 translation
、rotation
等属性。
import pymel.core as pm
cube = pm.polyCube()[0]
cube.translationX.set(1)
cube.translation.translationX.set(2)
cube.tx.set(3)
cube.t.tx.set(4)
# and more
我不明白这些属性是如何找到的,因为我找不到任何列出属性的文档? Transform
是否具有所有这些属性,其中每个属性都指向 DAG 节点的相应基础属性?映射发生在哪里以便找到正确的属性?
您可以只使用:
cube.listAttr()
我不确定他们是否包装了所有属性。
我自己有一个简单的 cmds 包装器,我只是通过覆盖动态添加节点的任何属性:getitem、getattr
这是 git 上的完整代码:https://github.com/DrWeeny/Whosebug/blob/master/59185039.py 这只是一个例子
class MAttr(object):
"""Represent a maya attribute
Args:
node (str): a string for the maya node affected
attr (str): a string that represent the attribute
Attributes:
attr_bypass (str): regex to bypass the compound attributes, because i need to connect and getattr
"""
attr_bypass = re.compile('\[(\d+)?:(\d+)?\]')
def __init__(self, node, attr='result'):
self.__dict__['node'] = node #: str: current priority node evaluated
self.__dict__['attribute'] = attr #: str: current priority node evaluated
self.__dict__['idx'] = 0 #: str: current priority node evaluated
def __getitem__(self, item):
"""
getitem has been overrided so you can select the compound attributes
``mn = MayaNode('cluster1')``
``mn.node.weightList[0]``
``mn.node.weightList[1].weights[0:100]``
Notes:
the notations with list[0:0:0] is class slice whereas list[0] is just and int
Args:
item (Any): should be slice class or an int
Returns:
cls : MAttr is updated with the chosen index/slice
"""
if isinstance(item, int):
self.__dict__['attribute'] = '{}[{}]'.format(self.attr, item)
else:
if not item.start and not item.stop and not item.step:
item = ':'
else:
item = ':'.join([str(i) for i in [item.start, item.stop, item.step] if i != None])
self.__dict__['attribute'] = '{}[{}]'.format(self.attr, item)
return self
def __getattr__(self, attr):
"""
__getattr__ is overriden in order to select attributes
Args:
attr (str): name of the attribute, even if we loop throught,
Returns:
str: it join all the attributes that has been chained : weightList[0].weight
"""
myattr = '{}.{}'.format(self.attr, attr)
if myattr in self.listAttr(myattr):
return MAttr(self._node, '{}.{}'.format(self.attr, attr))
else:
return self.__getattribute__(attr)
class MayaNode(object):
"""Represent a maya node as a class like pymel
Only provide the name as a string, if you use preset, you can create a new node
Note:
Should use maya api for getting the node
Args:
name (str): a string for the maya node you want to encapsulate
preset (:obj:`dict`, optional): Used for creating a new node from 'attrPreset'
you can also just specify the nodeType with a string instead
Attributes:
maya_attr_name (maya_data): Any attribute from the name will look for actual maya attribute
"""
def __init__(self, name, preset={}, blendValue=1):
# this dict method is used to avoid calling __getattr__
self.__dict__['node'] = name #: str: current priority node evaluated
self.__dict__['item'] = 1 #: int: can be either 0 or 1 and should be exented with Mesh or Cluster
if preset:
targ_ns = name.rsplit(':', 1)[0]
self.loadNode(preset, blendValue, targ_ns)
def __getitem__(self, item):
"""
getitem has been overrided so you can select the main nodes sh or tr so when you do:
``mn = MayaNode('pCube1')``
``mn[0].node`` result as the transform
``mn[1].node`` result as the shape
Note:
By default ``mn.node`` is the transform
"""
return self.setNode(item)
def __getattr__(self, attr):
"""
getattr has been overrided so you can select maya attributes and set them
if you type an attribute, it will try to find if it exists in either shape or transform
if it exists in both, it will always warn you that it returns shape in priority
``mn = MayaNode('pCube1')``
``mn.translateX = 10`` result in doing a cmds.setAttr
``mn.translateX.set(10)``
``mn.translateX.get()`` note that you to use get in order to do getAttr otherwise it __repr__ or __str__
``mn = MayaNode('cluster1')``
``mn.weightList[1].weights.get()`` is equivalent of cmds.getAttr('cluster1.weightList[1].weights[:]')
Note:
You cant have the value without .get()
"""
if attr in self.listAttr(attr):
return MAttr(self.node, attr)
elif attr in self.__dict__:
return self.__dict__[attr]
else:
try:
return self.__getattribute__(attr)
except AttributeError:
cmds.warning('{} doesn\'t exists, return None instead')
return None