Dealt Maya API. Here I decided to post some example functions. The basic idea was using Maya API Python classes realize workflow with extra attributes at native Maya node. Suppose you want to make a script that stores some data in one native Maya node (in the script node, for example), and if user do not have your script, nothing terrible will happen, node modified by you will work without any troubles. Sorry for my English.
You should get something like this:

import maya.OpenMaya as OpenMaya # general Maya API module
def addExtraAttrToNode( m_node_name ):
"""
add custom extra attributes to the node using Maya API
classes in runtime mode 'on fly'
INPUT: m_node_name - node name, like 'lambert1'
RETURN: True - if attributes added properly, False - otherwise
USAGE: addExtraAttrToNode('lambert1')
"""
# create selection list
#
m_selectionList = OpenMaya.MSelectionList()
# create MObject
#
m_node = OpenMaya.MObject()
# create a function set to work with MObject
#
m_node_fn = OpenMaya.MFnDependencyNode()
try:
# add node with name 'lambert2'
# if node don't exist return exception
m_selectionList.add( m_node_name )
except:
return False
# get first element in the selection list and connect with MObject
#
m_selectionList.getDependNode( 0, m_node )
# connect MObject with function set
#
m_node_fn.setObject( m_node )
#
# float attribute
#
fAttr = OpenMaya.MFnNumericAttribute()
aSampleFloat = OpenMaya.MObject()
aSampleFloat = fAttr.create( "sampleFloat", "sf",
OpenMaya.MFnNumericData.kFloat, 0.0 )
fAttr.setKeyable( True )
fAttr.setStorable( True )
fAttr.setDefault( 1.0 )
#
# string attribute
#
fAttr = OpenMaya.MFnTypedAttribute()
aSampleTxt = OpenMaya.MObject()
aSampleTxt = fAttr.create( "sampleTXT", "st",
OpenMaya.MFnData.kString )
fAttr.setKeyable( True )
fAttr.setWritable( True )
fAttr.setReadable( True )
fAttr.setStorable( True )
#
# boolean attribute
#
fAttr = OpenMaya.MFnNumericAttribute()
aSampleBool = OpenMaya.MObject()
aSampleBool = fAttr.create( "sampleBOOL", "sb",
OpenMaya.MFnNumericData.kBoolean, True )
fAttr.setKeyable( True )
fAttr.setStorable( True )
fAttr.setReadable( True )
fAttr.setWritable( True )
#
# multi compound attribute
#
fAttr = OpenMaya.MFnCompoundAttribute()
aCompound = OpenMaya.MObject()
aCompound = fAttr.create( "sampleCompound", "sc" )
fAttr.addChild( aSampleBool ) # child 0
fAttr.addChild( aSampleTxt ) # child 1
fAttr.addChild( aSampleFloat ) # child 2
fAttr.setArray( True ) # create 'multi' attr
fAttr.setKeyable( True )
fAttr.setWritable( True )
fAttr.setReadable( True )
fAttr.setStorable( True )
try:
# try to add attributes using function set
m_node_fn.addAttribute( aCompound )
except:
return False
return True
def printExtraAttrData( m_node_name ):
"""
print's data stored in extra attributes
INPUT: m_node_name - node name, like 'lambert1'
RETURN: True - if well done, False - otherwise
USAGE: printExtraAttrData('lambert1')
"""
m_selectionList = OpenMaya.MSelectionList() # create selection list
m_node = OpenMaya.MObject() # create MObject
m_node_fn = OpenMaya.MFnDependencyNode() # create a function set
try:
# add node with name 'lambert2'
m_selectionList.add( m_node_name )
except:
return False
# get first element in the selection list and connect with MObject
m_selectionList.getDependNode( 0, m_node )
# connect MObject with function set
m_node_fn.setObject( m_node )
# find attribute by name using function set class
#
m_attr = m_node_fn.attribute('sampleCompound')
# create MPlug object fo work with attribute
# A plug is a point on a dependency node where a
# particular attribute can be connected
m_attr_plug = OpenMaya.MPlug( m_node, m_attr )
# create int array fo storing indexes of available items
#
m_ind = OpenMaya.MIntArray()
m_attr_plug.getExistingArrayAttributeIndices(m_ind)
try:
for i in m_ind:
print("IND %s BOOL %s STR %s FLOAT %s"
%( i,
m_attr_plug.elementByLogicalIndex(i).child(0).asBool(),
m_attr_plug.elementByLogicalIndex(i).child(1).asString(),
m_attr_plug.elementByLogicalIndex(i).child(2).asFloat() ) )
except:
return False
return True
def setExtraAttrValues( m_node_name, m_index, m_tuple ):
"""
write data to the node
INPUT: m_node_name - node name, like 'lambert1'
m_index - index of item where you wont to write
m_tuple - tuple, like: ( True , 'Test', 4.2 )
m_tuple[0] - True
m_tuple[1] - 'Test'
m_tuple[2] - 4.2
RETURN: True - if well done, False - otherwise
USAGE: setExtraAttrValues( 'lambert1', 1, ( False , 'Test', 4.2 ) )
"""
m_selectionList = OpenMaya.MSelectionList()
m_node = OpenMaya.MObject()
m_node_fn = OpenMaya.MFnDependencyNode()
try:
m_selectionList.add( m_node_name )
m_selectionList.getDependNode( 0, m_node )
m_node_fn.setObject( m_node )
m_attr = m_node_fn.attribute('sampleCompound')
m_attr_plug = OpenMaya.MPlug( m_node, m_attr )
# convert m_index to integer
#
m_index = int(m_index)
# write data stored in tuple to the node
#
m_attr_plug.elementByLogicalIndex(m_index).child(0).setBool( m_tuple[0] )
m_attr_plug.elementByLogicalIndex(m_index).child(1).setString( m_tuple[1] )
m_attr_plug.elementByLogicalIndex(m_index).child(2).setFloat( m_tuple[2] )
except:
return False
return True
How you can use it:
addExtraAttrToNode('lambert1')
setExtraAttrValues('lambert1', 1, ( False , 'Test 1', 4.2 ) )
setExtraAttrValues('lambert1', 0, ( True , 'Test Message', 16.2 ) )
setExtraAttrValues('lambert1', 3, ( False , 'Test 2', 0.54 ) )
printExtraAttrData('lambert1')
In Maya console you should get:
IND 0 BOOL True STR Test Message FLOAT 16.2000007629 IND 1 BOOL False STR Test 1 FLOAT 4.19999980927 IND 3 BOOL False STR Test 2 FLOAT 0.540000021458