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