我要发布到目前为止的内容并尝试描述问题。
下面的脚本跟踪具有自定义属性的变换对象。它创建了一个易于__get__
和__set__
到maya节点属性的界面。这样可以轻松地将属性值保存到可以在将来加载场景的场景中。在脚本中,我使用OpenMaya来跟踪dagObject,但是简化为首先尝试解决问题。如果要使用此代码,请查看MDagPath和MSelectionList。
现在..
需要在Attributes()
之外声明__init__
才能正常工作。
Attributes()
就像现在一样,在创建时需要Transform()。
如果我在Transform()
中的__init__
之外创建Clip()
,则生成的Transform()
实例将引用此方法创建的最新Transform()
(图片)
无法在没有声望的情况下发布图片,因此描述性地: 三个名为_new_anim _,_ new_anim_1,_new_anim_2的剪辑。 运行脚本时,列表中的输出都是_new_anim_2,这是最初初始化的转换。
在创建属性后 __init__
发生。
我需要将__init__
Transform
实例传递给已初始化的Attribute实例。
如何?
说clip.transform = correctTransform
似乎无法替换correctTransfrom
的引用。我需要一种方法将类实例传递给在__init__
之外初始化的类变量。
import maya.cmds as cmds
class Attribute(object):
def __init__(self,transform,attr,*args):
self.transform = transform
self.attr = attr
self.string = "string" in args
def __set__(self, instance, value):
if self.string:
cmds.setAttr(self.transform.path()+"."+self.attr,value,dt="string")
else:
cmds.setAttr(self.transform.path()+"."+self.attr,value)
def __get__(self, instance, owner):
if self.string:
return cmds.getAttr(self.transform.path()+"."+self.attr,dt="string")
return cmds.getAttr(self.transform.path()+"."+self.attr)
class Transform(object):
def __init__(self):
self.parent = ""
self.name = ""
def setObject(self,transform):
self.parent = cmds.listRelatives(transform,p=1)[0]
self.name = cmds.ls(transform,sn=1)[0]
def path(self):
return self.parent+"|"+self.name
def getName(self):
return cmds.ls(self.path(),sn=1)[0]
def rename(self,value):
self.name = cmds.ls(cmds.rename(self.path(),value),sn=1)[0]
class Clip(object):
transform = Transform()
start = Attribute(transform,"STA")
end = Attribute(transform,"END")
loop = Attribute(transform,"Loop")
relative = Attribute(transform,"RelativeToStart")
speedState = Attribute(transform,"SpeedState")
speed = Attribute(transform,"SpeedVal")
def __init__(self,transform):
self.transform.setObject(transform)
答案 0 :(得分:1)
如果我正确理解您的问题,看起来您希望transform
类中的Clip
变量是特定于实例的值,但是您遇到问题因为它需要是由Attribute
描述符访问,您还要添加到Clip
,这需要声明为类变量。
我认为解决这个问题的方法是让Attribute
类的__get__
和__set__
方法在transform
上传递instance
,而不是self
。
试试这个:
class Attribute(object):
def __init__(self,attr,*args): # no transform parameter or instance variable
self.attr = attr
self.string = "string" in args
def __set__(self, instance, value): # look up transform on instance, rather than self
if self.string:
cmds.setAttr(instance.transform.path()+"."+self.attr,value,dt="string")
else:
cmds.setAttr(instance.transform.path()+"."+self.attr,value)
def __get__(self, instance, owner): # here too
if self.string:
return cmds.getAttr(instance.transform.path()+"."+self.attr,dt="string")
return cmds.getAttr(instance.transform.path()+"."+self.attr)
# Transform can stay the same, though you could merge set_object into __init__
class Clip(object):
# no more transform class variable
start = Attribute("STA") # no more transform argument passed to the Attributes
end = Attribute("END")
loop = Attribute("Loop")
relative = Attribute("RelativeToStart")
speedState = Attribute("SpeedState")
speed = Attribute("SpeedVal")
def __init__(self,transform):
self.transform = Transform() # create transform as an instance variable
self.transform.setObject(transform)