Wednesday, February 20, 2013

Storing attribute values with Maya API

This problem occurred as I was working on a tool that created attributes via maya api, and I had to set certain values on those attribs, and as I did so, I would save the file, and then re-open it, to find that the values I set were not being saved. Here is my original code:
import maya.OpenMaya as om
import maya.OpenMayaAnim as oma

depFn = om.MFnDependencyNode()
setObj = depFn.create("objectSet", "SaveLoadAnim")
uAttr = om.MFnUnitAttribute()

startAttr = uAttr.create("Start", "s", om.MFnUnitAttribute.kTime, oma.MAnimControl.minTime().value())
uAttr.setStorable(True)
uAttr.setKeyable(False)

endAttr = uAttr.create("End", "e", om.MFnUnitAttribute.kTime, oma.MAnimControl.maxTime().value())
uAttr.setStorable(True)
uAttr.setKeyable(False)

dgModifier = om.MDGModifier()

dgModifier.addAttribute(setObj, startAttr)
dgModifier.addAttribute(setObj, endAttr)

dgModifier.doIt()

If you run this code in maya, you'll notice that a set is created, and in the "Extra Attributes" there are 2 MTime attributes for "Start" and "End". They should be set as the current values of your scene's start/end. Now save this file somewhere, and re-open it. You'll notice that the values are now both set to 0... This quite confused me as I set the default value on the attributes creation as well as set the "storable" value to True...

After some digging around and talking to people about the issue, a colleague suggested that it might be the actual DG evaluation that might be causing the problem in setting this value to be stored with the attribute. His theory led me to think that it might be the case that DGModifier isn't flagging the default value as an actual value to be stored to the memory of the attribute as the DG isn't marked dirty on the attributes creation. And if it's not marked "dirty", the actual process of setting the attrib value inside the attribute itself just doesn't occur.

To test this idea I changed my code around a little, and - voilà! - it worked. So here is my final code:
import maya.OpenMaya as om
import maya.OpenMayaAnim as oma

depFn = om.MFnDependencyNode()
setObj = depFn.create("objectSet", "SaveLoadAnim")
uAttr = om.MFnUnitAttribute()

startAttr = uAttr.create("Start", "s", om.MFnUnitAttribute.kTime)
uAttr.setStorable(True)
uAttr.setKeyable(False)

endAttr = uAttr.create("End", "e", om.MFnUnitAttribute.kTime)
uAttr.setStorable(True)
uAttr.setKeyable(False)

dgModifier = om.MDGModifier()

dgModifier.addAttribute(setObj, startAttr)
dgModifier.addAttribute(setObj, endAttr)

dgModifier.doIt()

startPlug = depFn.findPlug(startAttr)
endPlug = depFn.findPlug(endAttr)

startPlug.setMTime(oma.MAnimControl.minTime())
endPlug.setMTime(oma.MAnimControl.maxTime())

Cheers,

DK