Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix for string attributes default values #39

Closed
55 changes: 50 additions & 5 deletions cmdx.py
Original file line number Diff line number Diff line change
Expand Up @@ -1022,10 +1022,20 @@ def addAttr(self, attr):

"""

if isinstance(attr, _AbstractAttribute):
attr = attr.create()
attr_obj = attr.create() if isinstance(attr, _AbstractAttribute) else attr
self._fn.addAttribute(attr_obj)

# workaround for string attribute default value, see String.default() for details
def setAttr(attr):
if isinstance(attr, String):
default = _AbstractAttribute.default(attr)
if default:
self.findPlug(attr["name"]).setString(default)
elif isinstance(attr, Compound):
for child in attr["children"]:
setAttr(child)
setAttr(attr)

self._fn.addAttribute(attr)

def hasAttr(self, attr):
"""Return whether or not `attr` exists
Expand Down Expand Up @@ -5120,8 +5130,43 @@ class String(_AbstractAttribute):
Default = ""

def default(self, cls=None):
default = str(super(String, self).default(cls))
return om.MFnStringData().create(default)
"""
string attributes can't have default values (http://help.autodesk.com/cloudhelp/2020/ENU/Maya-Tech-Docs/Commands/addAttr.html#flagdefaultValue),
or at least it isn't saved in scenes (https://github.com/mottosso/cmdx/issues/34)
-> don't pass the default to OpenMaya, instead set it during Node.addAttr()

Test:
>>> import os
>>> os.environ["CMDX_SAFE_MODE"] = "True" # disable caching (node/plug reuse)
>>> import cmdx
>>> # new scene with a sphere with "my_string" attribute
>>> _ = cmds.file(new=True, force=True)
>>> sphere_name = cmds.sphere()[0]
>>> sphere = cmdx.encode(sphere_name)
>>> sphere.add_attr(cmdx.String("my_string", default="foo"))
>>> sphere["my_string"].name()
'my_string'
>>> # save scene
>>> import tempfile
>>> scene_file = tempfile.NamedTemporaryFile(prefix="test_string_attribute_", suffix=".ma")
>>> scene_path = scene_file.name
>>> _ = cmds.file(rename=scene_path)
>>> _ = cmds.file(save=True, type="mayaAscii")
>>> # reload scene & check "my_string"
>>> _ = cmds.file(scene_path, open=True, force=True)
>>> sphere = cmdx.encode(sphere_name)
>>> str(sphere)
'|nurbsSphere1'
>>> if sphere["my_string"].name() != "my_string":
... print(scene_path)
... with open(scene_path) as f: print(f.read())
>>> sphere["my_string"].name()
'my_string'
>>> scene_file.close() # deletes the temp file (supposedly)
>>> sphere["my_string"].read()
u'foo'
"""
return None

def read(self, data):
return data.inputValue(self["mobject"]).asString()
Expand Down