This patch adds support for disabling outputs in built-in nodes based on
menu inputs using a custom usage_inference callback. This just
essentially calls usage_inference_fn for outputs as well, while it was
only being called for inputs. Additionally, the usage_by_menu methods
were adjusted to only consider outputs if it is being called on inputs.
Some types were renamed to be more general, and not just for inputs.
Pull Request: https://projects.blender.org/blender/blender/pulls/148132
This extracts the construction of the `SocketValueInferencer` out of
`SocketUsageInferencer`. This leads to better separation of concerns and gives
the caller more flexibility. In the future, I especially want to get information
about which group input values were required to determine the usage of other
group inputs. This might help with caching the inferenced values.
Pull Request: https://projects.blender.org/blender/blender/pulls/147352
The pattern here is very similar to `SocketValueInferencer`. The goal is to make
it easier to reuse this functionality without calling a higher level wrapper
like `infer_group_interface_usage`. This is especially useful when determining
the usage of just a subset of group inputs. I intend to use that to speedup the
detection of what gizmos should be displayed in
`foreach_active_gizmo_exposed_to_modifier`.
Pull Request: https://projects.blender.org/blender/blender/pulls/147234
Currently, only the visibility of input sockets can be changed dynamically based
on other menu inputs. However, under some circumstances, it can also be useful
to hide certain outputs. For example, the built-in Curve Arc primitive node does
that.
This patch adds support for automatic detection of unused outputs. How to detect
unused outputs is less straight forward compared to inputs. This patch uses the
rule that an output is unused if it always outputs a "fallback value" (typically
0) irrespective of the currently used inputs. If the output is independent of
all inputs, it stays visible though.
There is a new small utility node called "Enable Output". It replaces a value
with it's fallback value unless it is disabled. This simplifies setting up
unused outputs. In theory, a normal switch node can also be used, but that is
less usable and the user will have to hardcode the fallback value for each type
which is not something that is explicitly exposed yet.
Supporting dynamic output visibility is also a prerequisite for exposing some
menu node options as sockets (e.g. in the Arc node).
Pull Request: https://projects.blender.org/blender/blender/pulls/140856
Geometry Nodes used a `PropertiesVectorSet` in some places to allow
constant-time `IDProperty` access by name in a group. This used to be a
bottleneck in node groups with hundreds of inputs. Now this separate hash table
is not necessary anymore, because it's `IDProperty` groups now support this
directly since 6cb2226f13.
This also adds a `IDP_GetPropertyFromGroup_null` utility function to be able to
do this refactor more safely. Null pointers were allowed before.
Pull Request: https://projects.blender.org/blender/blender/pulls/146152
Currently, `InferenceValue` contains either a primitive value or is in the
"unknown" state. Previously, all code had the assumption that when the value is
not unknown, it is a primitive value. However, that may not be true anymore when
we support inferencing through e.g. bundles and closures as those are not
"primitive". This assumption is removed now, non-primitive values have not been
added yet though.
Pull Request: https://projects.blender.org/blender/blender/pulls/145532
Value and usage inferencing can be done independently. Usage-inferencing uses
the value-inferencing but not the other way around. Extracting value-inferencing
makes the separation more clear and also simplifies potentially reusing the
value-inferencing code later on.
Pull Request: https://projects.blender.org/blender/blender/pulls/145492
So far, only node group were able to have menu input sockets. Built-in nodes did
not support them. Currently, all menus of built-in nodes are stored on the node
instead of on the sockets. This limits their flexibility because it's not
possible to expose these inputs.
This patch adds initial support for having menu inputs in built-in nodes. For
testing purposes, it also changes a couple built-in nodes to use an input socket
instead of a node property: Points to Volume, Transform Geometry, Triangulate,
Volume to Mesh and Match String.
### Compatibility
Forward and backward compatibility is maintained where possible (it's not
possible when the menu input is linked in 5.0). The overall compatibility
approach is the same as what was done for the compositor with two differences:
there are no wrapper RNA properties (not necessary for 5.0, those were removed
for the compositor already too), no need to version animation (animation on the
menu properties was already disabled).
This also makes menu sockets not animatable in general which is kind of brittle
(e.g. doesn't properly update when the menu definition changes). To animate a
menu it's better to animate an integer and to drive an index switch with it.
### Which nodes to update?
Many existing menu properties can become sockets, but it's currently not the
intention to convert all of them. In some cases, converting them might restrict
future improvements too much. This mainly affects Math nodes.
Other existing nodes should be updated but are a bit more tricky to update for
different reasons:
* We don't support dynamic output visibility yet. This is something I'll need to
look into at some point.
* They are shared with shader/compositor nodes, which may be more limited in
what can become a socket.
* There may be performance implications unless extra special cases are
implemented, especially for multi-function nodes.
* Some nodes use socket renaming instead of dynamic socket visibility which
isn't something we support more generally yet.
### Implementation
The core implementation is fairly straight forward. The heavy lifting is done by
the existing socket visibility inferencing. There is a new simple API that
allows individual nodes to implement custom input-usage-rules based on other
inputs in a decentralized way.
In most cases, the nodes to update just have a single menu, so there is a new
node-declaration utility that links a socket to a specific value of the menu
input. This internally handles the usage inferencing as well as making the
socket available when using link-drag-search.
In the modified nodes, I also had to explicitly set the "main input" now which
is used when inserting the node in a link. The automatic behavior doesn't work
currently when the first input is a menu. This is something we'll have to solve
more generally at some point but is out of scope for this patch.
Pull Request: https://projects.blender.org/blender/blender/pulls/140705
Previously, when a socket was detected to be unused, it was just grayed out.
This patch adds support for automatically hiding unused sockets based on this
convention: Menu inputs control visibility while other inputs only control
whether something is grayed out.
More specifically, an input is visible if any of these conditions is met:
* It affects the output currently.
* It never affects the output. In this case its usage does not depend on any
menu input.
* It is used if all non-menu inputs are considered to be unknown.
In the future, we could support customizing which inputs are allowed to control
visibility. For now it's good to use the convention that Blender generally
follows itself.
As before, panels are grayed out if they only contain grayed out sockets and
panels are hidden when they don't contain any visible sockets.
Hiding inputs works in group nodes, the Geometry Nodes modifier and node
operators. In theory it will work for all node tree types, but since only
Geometry Nodes supports the Menu Switch node currently, this patch currently
only makes a difference there.
The implementation reuses the existing `SocketUsageInferencer` with a different
sets of inputs. So no new core-inferencing logic was needed.
Design task: #132706.
Pull Request: https://projects.blender.org/blender/blender/pulls/138186
Resolves#136183
To avoid quadratic worst case runtime when gathering values from
the modifier properties, build a temporary VectorSet of the modifier's
IDProperties. In the file from #136183, this change improves playback
performance by 1.4x for me, from 50 to 70ms.
Ideally IDProperty groups would have constant time lookup on their
own, but that's a much larger change, and this smaller change for just
Geometry Nodes is not so invasive.
Pull Request: https://projects.blender.org/blender/blender/pulls/136463
This patch automatically grays out input values which can't affect the output
currently. It works with inputs of group nodes, geometry nodes modifiers and
node tools.
To achieve this, it analyses the node tree and partially evaluates it to figure
out which group inputs are currently not linked to an output or are disabled by e.g.
some switch node.
Original proposal: https://devtalk.blender.org/t/dynamic-socket-visibility/31874
Related info in blog post:
https://code.blender.org/2023/11/geometry-nodes-workshop-november-2023/#dynamic-socket-visibility
Follow up task for designing a UI that allows hiding sockets: #132706
Limitations:
* The inferencing does not update correctly when a socket starts being
animated/driven. I haven't found a good way to invalidate the cache in a good
way reliably yet. It's only a very short term problem though. It fixes itself
after the next modification of the node tree and is only noticeable when
animating some specific sockets such as the switch node condition.
* Whether a socket is grayed out is not exposed in the Python API yet. That will
be done separately.
* Only a partial evaluation is done to determine if an input affects an output.
There should be no cases where a socket is found to be unused when it can actually
affect the output. However, there can be cases where a socket is inferenced to be used
even if it is not due to some complex condition. Depending on the exact circumstances,
this can either be improved or the condition in the node tree should be simplified.
Pull Request: https://projects.blender.org/blender/blender/pulls/132219