[Max] C# Api. Access Controller/Sub Anim Values

Hey All

I’m dipping my toe into the max c# api. I’m trying to access the values of a node’s basic transform sub anim tree but i’m running in to issues.

The code below is some simple code that should recurse the sub anim tree of a selected node (INode) and show a tree view representing the controller tree.

I want the tree to also show the current value of the sub anim, so i’m trying to access the ‘value’ via a parameter block (i gather from the docs that’s how they are stored and accessed).

However i am unable to access any parameter blocks. in the code below numberOfParamBlocks is always zero.

So i’m stumped on how to access the data. I’m not sure if i’m going about this all wrong?

        
/// <summary>
/// Recursive function that adds tree items for each sub anim and its values
/// </summary>
/// <param name="subAnim"></param>
/// <param name="fullList"></param>
/// <param name="treeParentItem"></param>
private void recurseSubAnims(IAnimatable subAnim, List<IAnimatable> fullList, TreeViewItem treeParentItem = null)
{
    // create a tree node for the current sub anim
    TreeViewItem treeItem = new TreeViewItem();
    string saName = subAnim.ClassName.ToString();
    treeItem.Header = saName;
    treeParentItem.Items.Add(treeItem);
            
    // loop the child sub anims
    for (int i = 0; i < subAnim.NumSubs; i++)
    {
        // current child sub anim
        IAnimatable childSubAnim = subAnim.SubAnim(i) as IAnimatable;

        if (childSubAnim != null)
        {

            // store the number of param blocks... for debugging                    
            int numberOfParamBlocks = childSubAnim.NumParamBlocks; // ALWAYS 0!

            // loop the parameter blocks to get acces to the data values..
            for (int pb_i = 0; pb_i < numberOfParamBlocks; pb_i++)
            {
                // NEVER GET HERE!!

                // create an object variable for the unknown data type.
                object val ;

                // get the current param block
                IIParamBlock2 pb = childSubAnim.GetParamBlock(pb_i);                        
                        
                // time variable for the getValue()
                int time = (int)MaxUtils.maxIntr.Time;

                // seems the getValue needs this...
                Autodesk.Max.MaxSDK.AssetManagement.IAssetUser au = null;

                // and also this...
                IInterval ivalid = null;

                // get the value. 
                pb.GetValue(1, MaxUtils.maxIntr.Time, au, ivalid, -1);

                // add a tree item representing the value
                TreeViewItem valTreeItem = new TreeViewItem();
                treeItem.Items.Add(valTreeItem);

                // recurse
                this.recurseSubAnims(childSubAnim, fullList, treeItem);
            }
        }
    }
}
        
/// <summary>
/// Main populate method for the tree node
/// </summary>
/// <param name="node"></param>
public void populateTree( IINode node ){

    // list that will be populated by reference
    List<IAnimatable> fullList = new List<IAnimatable>();
            
    // get a list of all selected nodes.
    List<IINode> selectedNodes = MaxUtils.getSelectedNodes();
            
    // loop the selected nodes
    for (int i = 0; i < selectedNodes.Count; i++)
    {
        // variable to current Inode
        IINode maxNode = selectedNodes[i];

        // create a tree item
        TreeViewItem nodeTreeItem = new TreeViewItem();
        nodeTreeItem.Header = maxNode.Name;
        this.treeView_subAnims.Items.Add(nodeTreeItem);

        // im just casting varibles so i can see them in debugging...
        int numSubs = maxNode.NumSubs;
                  
        // loop the sub anims
        for (int tr = 0; tr < numSubs; tr++)
        {
            // current sub anim
            IAnimatable childSubAnim = maxNode.SubAnim(tr);

            if (childSubAnim != null)
            {
                // kick off main recurse
                this.recurseSubAnims(childSubAnim, fullList, nodeTreeItem);
            }

        }
    }
}

Thanks for any help.

just quick guess, after searching the SDK

does EnumAnimTree do what you need?

This method recursively enumerates the Animatable hierarchy. It will call the AnimEnum::proc() method passing it the anim, that anim’s parent (the client), and the sub-anim index of that anim to the client, for every anim and sub-anim in the hierarchy.

disclaimer: No idea what I’m talking about…