SOLVED Node Editor API - Active Node Editor Graph?

Hi,

Is there a way to access the current/active graph in the Node Editor via the Python API? I'm trying to write some node layout helpers (Align Horizontal/Vertical) but I'm not finding the information I'm looking for.

  1. How can I get the current graph that's visible/active in the Node editor?
    • c4d.GetActiveNodeSpaceId() doesn't change when I switch from material nodes to scene nodes.
    • Even for a materials-only mode, the selection state of a material doesn't indicate which graph is currently selected.
    • How do we determine which of the open node editors is active (like in Edit Asset mode)?

hi Donovan,

@dskeith said in Node Editor API - Active Node Editor Graph?:

c4d.GetActiveNodeSpaceId() doesn't change when I switch from material nodes to scene nodes.

The nodespace is something you can change in the 'Render -> Node Space' menu. It will act like a filter; it does not make any sense to have nodes for redshift material inside the standard material and is related to the render you are using. By default, if you change the render, it will automatically change the nodepspace to match the Render Engine. As the scene node is not affected by the nodespace.

As you said, you can have multiple node editor opened at the same time. They can display various place of a node system and various nodespaces. You cannot retrieve which one is active even if it was possible the information is not accessible.

Those Node Editor share some information. If you select a node in one editor, it will be selected among all the editors. But the coordinates of each node are defined per editor. There is an attribut for that, but it is currently like a BlackBox and could change in the futur.

We have an example on how to retrieve the scene node in our Asset Browser examples. We need to create more specific example for the Node Module itself.

Is there a concept of "sub-graphs"? For example, if the user has navigated inside of a group in the Node Editor, and they run "Select Node Parents" it will also select parents outside of the currently visible group. Whereas, they probably only want to select the parents visible within their current context.

There is a IsGroup function to check if the parent is a group or not. This function does not seem to be available in python. Or you could also check if the parent is the same as the root.

I hope i got all the questions

Cheers,
Manuel

Here's the code working for materials. How would I expand it to also work with Scene Nodes and, ideally, to work with the currently active node editor?

"""Name-en-US: Select Node Children
Description-en-US: Selects Child Nodes

Copyright: MAXON Computer GmbH
Author: Donovan Keith

Adapted from a script by
Copyright: MAXON Computer GmbH
Author: Manuel Magalhaes

Version: 0.1.0

## Changelog

- v0.1.0: Initial Release

"""
import c4d
import maxon


def main():
    c4d.GetActiveNodeSpaceId()

    # Get the Active Material
    # ISSUE: It's possible to have the node editor editing a material even if its not active/selected (Asset Mode, Lock mode, etc)
    mat = doc.GetActiveMaterial()
    if mat is None:
        raise ValueError("There is no selected BaseMaterial")

    # Retrieve the reference of the material as a node Material.
    nodeMaterial = mat.GetNodeMaterialReference()
    if nodeMaterial is None:
        raise ValueError("Can't retrieve nodeMaterial reference")

    # Retrieve the current node space Id
    nodespaceId = c4d.GetActiveNodeSpaceId()

    # Retrieve the graph corresponding to that nodeSpace.
    graph = nodeMaterial.GetGraph(nodespaceId)
    if graph is None:
        raise ValueError("Can't retrieve the graph of this nimbus ref")

    with graph.BeginTransaction() as transaction:
        selected_nodes = []
        maxon.GraphModelHelper.GetSelectedNodes(graph, maxon.NODE_KIND.NODE, selected_nodes)

        predecessors = []
        for node in selected_nodes:
            maxon.GraphModelHelper.GetAllPredecessors(node, maxon.NODE_KIND.NODE, predecessors)

        for predecessor in predecessors:
            maxon.GraphModelHelper.SelectNode(predecessor)

        transaction.Commit()

    # Pushes an update event to Cinema 4D
    c4d.EventAdd()


if __name__ == "__main__":
    main()

Now that I'm realizing you can have multiple open Node Editors, some w/ locking, some without, I can imagine this being a similar challenge to the "Which timeline is active?" problem.

How to Get the Selected Keyframes in Active Timeline/FCurve Manager | PluginCafé
Get Active Timeline Request | PluginCafé

Realizing there are even more considerations:

  1. Is there a concept of "sub-graphs"? For example, if the user has navigated inside of a group in the Node Editor, and they run "Select Node Parents" it will also select parents outside of the currently visible group. Whereas, they probably only want to select the parents visible within their current context.

hi Donovan,

@dskeith said in Node Editor API - Active Node Editor Graph?:

c4d.GetActiveNodeSpaceId() doesn't change when I switch from material nodes to scene nodes.

The nodespace is something you can change in the 'Render -> Node Space' menu. It will act like a filter; it does not make any sense to have nodes for redshift material inside the standard material and is related to the render you are using. By default, if you change the render, it will automatically change the nodepspace to match the Render Engine. As the scene node is not affected by the nodespace.

As you said, you can have multiple node editor opened at the same time. They can display various place of a node system and various nodespaces. You cannot retrieve which one is active even if it was possible the information is not accessible.

Those Node Editor share some information. If you select a node in one editor, it will be selected among all the editors. But the coordinates of each node are defined per editor. There is an attribut for that, but it is currently like a BlackBox and could change in the futur.

We have an example on how to retrieve the scene node in our Asset Browser examples. We need to create more specific example for the Node Module itself.

Is there a concept of "sub-graphs"? For example, if the user has navigated inside of a group in the Node Editor, and they run "Select Node Parents" it will also select parents outside of the currently visible group. Whereas, they probably only want to select the parents visible within their current context.

There is a IsGroup function to check if the parent is a group or not. This function does not seem to be available in python. Or you could also check if the parent is the same as the root.

I hope i got all the questions

Cheers,
Manuel

Gotcha. So, at least for now, we can't develop tools/commands for manipulating nodes in the "active" node editor. Thanks for the thorough response! The GetSceneNodesGraph method is really useful, might be worth adding it into the API as a convenience function. Same for a GetActiveMaterialNodeGraph() or something similar for materials.

Hello @dskeith,

without any further questions and other postings, we will consider this topic as solved and flag it as such by Friday, 17/06/2022.

Thank you for your understanding,
Ferdinand