One of our mid-term goals is to expose all node inputs as sockets. That is currently not the case for two main reasons:
- We do not have socket types for all different data types that we want to expose. Among others, we are missing socket types for enums, color ramps and curves.
- Sometimes changing the values that are not exposed as sockets changes which sockets are available. We don’t have a system to change the set of visible sockets depending on other sockets.
Both of these limitations are solvable. This proposal describes one way how enum sockets can work. Enum properties are the main properties that we use in many nodes that are not exposed as sockets yet. The other mentioned limitations will be worked on separately.
Goal and Challenge
The goal is to add a new socket type for enums. It should work for built-in as well as user-defined enums.
What makes enums more difficult than the other socket types we have already is that different sockets show very different values. We need some system that determines which values are possible for an enum socket depending on what it is ultimately connected to.
Note how the Switch node inputs have to know what enum values are allowed.
Prototype
I’ve build a small prototype to test how enum sockets with inferencing can work in practice. It can be downloaded from the build-bot.
The prototype currently supports the following features:
- Enum socket that works with built-in and user-defined enums.
- Built-in enums are used by the Collection Info and Fill Curve nodes.
- User-defined enums can be created with the Enum node.
- The Switch node supports switching enums.
- Enum sockets can be exposed to the parent node group.
- Detection of cases where an output enum is connected to multiple incompatible enum inputs.
Using built-in enums is probably fairly self-explanatory. So I’ll focus on the design of the Enum node now (btw, feel free to suggest alternative names to “Enum”).
Enum Node
The new Enum node creates a new user-defined enum. In the node, one can simply add new items to the enum. By connecting the enum input socket to e.g. a Group Input node, the enum can be exposed to the outside.
The node has a bunch of outputs. First there is the Index output which gives an integer for the index of the passed in enum value. This value will be useful with an updated index-based switch node. If the passed in value is invalid, it currently outputs -1. Furthermore, for every enum item there is a boolean output. They all output false except for the one that corresponds to the passed in enum value.
One important note: when the node is copied, a completely new and incompatible user-defined enum is created, even if it has the same elements in the beginning. To reuse the same Enum node in multiple places, it has to be put into a group.
Conclusion
The approach implemented in the prototype seems to be a good solution. It would be helpful to get some feedback on the following topics:
- Do you see any downsides with the general solution implemented in the prototype?
- Are there other possible solutions which work just as well or better?
- Do you have any examples from the past where you wanted to expose enum sockets but did not just because you couldn’t?
- Would you want to use enum sockets for building node-group assets? Do you have some examples you’d like to use them for?