Maya API How-To #17

Back · Previous · Next Maya

How do I initialize a string attribute's default when it is added?

A string attribute is created using the typed attribute function set: MFnTypedAttribute. To set a default value for a typed attribute you must first create a MObject for that type's data.

You can set the default values for attributes at the same time they are created. The following excerpt from a node's ::initialize() method depicts an example for a string attribute:

MObject myNode::aStringAttr;

MStatus myNode::initialize()
{
  // Declare the function set for a typed attribute.
  MFnTypedAttribute                     tAttr;

  // Declare the function set and a MObject for the attribute data.
  MFnStringData                         fnStringData;
  MObject                               defaultString;

  // Create the default string.
  defaultString = fnStringData.create( "Default String" );

  // Create the attribute and specify its default.
  aStringAttr = tAttr.create( "string", "str", MFnData::kString, defaultString );

  tAttr.setStorable(true);
  tAttr.setKeyable(false);

  status = addAttribute( aStringAttr );
  if (!status) { status.perror("addAttribute .string"); return status;}
}

A Gotcha with Dynamic Attributes

The above method works find within an MPxNode::initialize() method. However, if you are adding a dynamic string attribute via an MPxCommand you'll find that, although the node's attribute does indeed have a default string, the default will not "stick" after saving and reloading scene. In other words, if you save the scene without modifying the default, then reload the scene, the string value will disappear.

This is a side-effect of one of Maya's optimizations: If an attribute's value is equal to its default, Maya does not store the attribute on save. Usually this is not an issue, because the attribute is added with knowledge of its default value. Something is amiss with dynamic string attributes, however, as the default is not specified in the 'addAttr' command.

The workaround for this is to add the attribute with a NULL default value, and set the attribute's value via its MPlug immediately after adding it:

static const char kDefaultString[] = "Default String";

MStatus myCommand::AddAttribute( MObject & node )
{
  MStatus                               status;

  MDGModifier                           dgModifier;
  MFnTypedAttribute                     tAttr;

  aStringWithDefault = tAttr.create( "string", "str", MFnData::kString, MObject::kNullObj );
  fnTypedAttr.setStorable(true);
  fnTypedAttr.setKeyable(false);

  status = dgModifier.addAttribute( node, aStringWithDefault );
  status = dgModifier.doIt();

  // The default for the string attribute does not "stick" after a
  // save and reload; explicitly set it via its MPlug.
  MPlug plug( node, aStringWithDefault );
  plug.setValue( kDefaultString );

  return status;
}

04 January 2003