Overview page for Node Groups Redesign project.
The general rationale has been laid out in this rather long blog post.
The current patch version implements some of the proposed features, listed in detail below. The latest version of the code can be found here:
Node Group Interfaces
- Two new node types added: NODE_PROXY_INPUT and NODE_PROXY_OUTPUT
- These function as internal representation of inputs and outputs of group nodes in the group node tree. These use their own custom theme color to make them easily visible in a node tree.
- inputs/outputs ListBase in bNodeTree are deprecated now (was storing bNodeSocket lists before). Instead the proxy_inputs/proxy_outputs lists are used to define ordering of interface sockets. They store bNodeProxyItems as a secondary list of node pointers. inputs/outputs lists must be kept around for do_versions code.
- Management of the list is done in the central nodeAddNode, nodeCopyNode and nodeFreeNode functions.
- I tried implementing this as part of the init/copy/free callbacks of the node type, but this leads to problems with do_versions, as the ntree pointer must be stored in the node. Current solution is simple and robust.
- do_versions code for node groups is rather complicated. It already required (since 2.56.2) some changes to be done after lib-linking (initializing node types, verifying static socket templates for changed nodes, syncing unique indices own_index between group nodes and internal sockets, and finally making an update call to make regular group sync), which uses an ugly extra do_versions method.
- With the new code replacing the previous "list of bNodeSockets" implementation by regular (proxy) nodes, this means another layer of do_versions code on top of the old code. Node sockets expose function also use a slightly different implementation (due to changes in input value storage first introduced in 2.59), so the old implementation had to be added directly in readfile.c (do_versions_node_group_add_socket_2_56_2).
- Forward compatibility is broken in current implementation . In order to reliably get working files in older Blender versions, the old "list of sockets" for group node interfaces will have to be restored on each file write (otherwise all node interfaces will simply be lost, proxy nodes are deleted due to missing types in older versions). This means a slight overhead in data and more difficult code for old unused stuff to maintain in writefile.c, as well as potential memory leaks.
- bNodeSocket groupsock pointers are deprecated as well. They are basically a shortcut from external node sockets to the internal sockets that nodes inside the group can link to. But this just means an additional set of inter-ID pointers (Note: pointer between data in different ID blocks, not to an ID block itself!) that need to be kept track of and has no practical value in the node editor whatsoever.
- The actual unique identifier to match external and internal sockets is always the own_index number on both sides. This should also be used by execution systems when converting node groups into internal graph formats.
- Groups are not displayed in a separate "bounding box" any more. The editor now shows all trees in the same way, regardless of whether they're top-level or node group trees. All specialized draw functions for node groups have therefore been removed.
- NODE_GROUP_EDIT flag for nodes is deprecated. Whether a node tree is shown in an editor window is now only defined by the editor SpaceNode (edittree is the currently shown tree). It allows different editors to actually show different node groups (see #Pinning section). The downside is that current hackish update methods for refreshing previews, etc. may not work as nicely as before. These often relied on a single path of visible node trees, now they basically have to update every tree in the hierarchy, starting from the material/scene/texture base tree. This can only be solved properly with a more potent depgraph implementation ... ( Also needs some more testing to make sure we at least get updates when needed, even though they may not be fast).
- SpaceNode now stores a path of node trees to keep track of the edited node groups. Every time a node group is edited it is placed on top of the path stack. Closing the group means popping the top item from the path and going back to the previous tree. This way different node editor areas can actually show different node trees (this was determined 100% by context until now).
- Every time the path top item changes (context switch or group open/close), the snode->edittree is updated to point to the currently displayed and edited tree.
- The node path is displayed as a string in the lower left corner, as an indication of the actual current edited tree. Some thought is needed on how to make this more intuitive and visible. Possibly different separators in the path or some different shading based on group level.
- Context switches are more restrictive about updating the tree pointer info in SpaceNode, to avoid constantly resetting the editing group node (also used for #Pinning). Only if the base snode->nodetree really changes will the node tree path be reset to a different base tree.
- Pinning can be controlled with a flag in SpaceNode. When set, the node path in SpaceNode will not be reset on context switches.
- It should be possible to explicitly select a node tree from the library for editing when pinning is enabled.