Search code examples
maya

How to get data from an upstream node in maya?


I have a maya node myNode, which creates a shadeNode, which inMesh attribute is connected to shapeNode.outMesh and has an attribute distance.

myNode.outMesh -> shapeNode.inMesh
myNode.distance = 10

Then i have a command, which works on the shape node, but requires the distance argument, which it does by iterating over the inMesh connections:

MPlugArray meshConnections;
MPlug inMeshPlug = depNodeFn.findPlug("inMesh"); 
inMeshPlug.connectedTo(meshConnections, true, false); // in connections

bool node_found = false;
for(uint i = 0; i < numConnections; i++) {
    MPlug remotePlug = meshConnections[i];
    myNode = remotePlug.node();
    if(MFnDependencyNode(myNode ).typeName() == "myNode") {
        node_found = true;
        break;
    }
}
MFnDependencyNode myDepNode(myNode);
MPlug distancePlug = myDepNode.findPlug("distance");

Now i get a problem, when applying another node (of another type) to myShape, because the dependency graph now looks like this:

myNode.outMesh -> myOtherNode.inMesh
                  myOtherNode.outMesh -> shapeNode.inMesh
myNode.distance = 10

I tried to remove the check for typeName() == "myNode", because i understood the documentation like there should be recursion to the parent node, when the next node return Mstatus::kInvalidParameter for the unknown MPlug, but i cannot reach the distance plug without implementing further graph traversion.

What is the correct way to reliably find an attribute of a parent node, even when some other nodes were added in between?

The command itself should use the distance Plug to either connect to myNode or to some plug which gets the value recursively. If possible i do not want to change myOtherNode to have a distance plug and correspondig connections for forwarding the data.


Solution

  • I found the answer in an answer (python code) to the question how to get all nodes in the graph. My code to find the node in the MPxCommand now looks like this:

    MPlugArray meshConnections;
    MPlug inMeshPlug = depNodeFn.findPlug("inMesh"); 
    MItDependencyGraph depGraphIt(inMeshPlug, MFn::kInvalid, MItDependencyGraph::Direction::kUpstream);
    bool offset_mesh_node_found = false;
    while(!depGraphIt.isDone()) {
        myNode = depGraphIt.currentItem();
        if(MFnDependencyNode(myNode).typeName() == "myNode") {
            offset_mesh_node_found = true;
            break;
        }
        depGraphIt.next();
    }
    

    The MItDependencyGraph can traverse the graph in upstream or downstream direction either starting from an object or a plug. Here i just search for the first instance of myNode, as I assume there will only be one in my use case. It then connects the distance MPlug in the graph, which still works when more mesh transforms are inserted.

    The MItDependencyGraph object allows to filter for node ids, but only the numeric node ids not node names. I probably add a filter later, when I have unique maya ids assigned in all plugins.