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
The `bNode.type_legacy` is still used in many places to check if a node is a
specific type. However, going forward it's better to rely more on the idname
than on this legacy integer type. Some more information is available in #132858.
The added utility method can be used like so:
`node->is_type("GeometryNodeMenuSwitch")`. Previously one would have written
`node->type_legacy == GEO_NODE_MENU_SWITCH`. The `is_type` method internally
checks that the passed in string is a valid node identifier to make it more
likely that we catch typos early.
Pull Request: https://projects.blender.org/blender/blender/pulls/132863
The new description for `bNode.type_legacy`:
```
/**
* Legacy integer type for nodes. It does not uniquely identify a node type, only the `idname`
* does that. For example, all custom nodes use #NODE_CUSTOM but do have different idnames.
* This is mainly kept for compatibility reasons.
*
* Currently, this type is also used in many parts of Blender, but that should slowly be phased
* out by either relying on idnames, accessor methods like `node.is_reroute()`.
*
* A main benefit of this integer type over using idnames currently is that integer comparison is
* much cheaper than string comparison, especially if many idnames have the same prefix (e.g.
* "GeometryNode"). Eventually, we could introduce cheap-to-compare runtime identifier for node
* types. That could mean e.g. using `ustring` for idnames (where string comparison is just
* pointer comparison), or using a run-time generated integer that is automatically assigned when
* node types are registered.
*/
```
Pull Request: https://projects.blender.org/blender/blender/pulls/132858
When using clangd or running clang-tidy on headers there are
currently many errors. These are noisy in IDEs, make auto fixes
impossible, and break features like code completion, refactoring
and navigation.
This makes source/blender headers work by themselves, which is
generally the goal anyway. But #includes and forward declarations
were often incomplete.
* Add #includes and forward declarations
* Add IWYU pragma: export in a few places
* Remove some unused #includes (but there are many more)
* Tweak ShaderCreateInfo macros to work better with clangd
Some types of headers still have errors, these could be fixed or
worked around with more investigation. Mostly preprocessor
template headers like NOD_static_types.h.
Note that that disabling WITH_UNITY_BUILD is required for clangd to
work properly, otherwise compile_commands.json does not contain
the information for the relevant source files.
For more details see the developer docs:
https://developer.blender.org/docs/handbook/tooling/clangd/
Pull Request: https://projects.blender.org/blender/blender/pulls/132608
The `socket->index_in_tree()` method provides a unique index for that socket
in the node tree (it's a cached runtime value). By construction, all input/output
sockets of a node have consecutive numbers, but this (sometimes useful) fact
is currently not exposed in the API.
This patch adds new `input_socket_indices_in_tree` and
`output_socket_indices_in_tree` methods to get the range of indices for all
inputs or outputs of a node.
Previously, the code was O(n^2) because it iterated over all interface sockets,
and for each it tried to find the corresponding index by iterating over all
inputs again. Now, a `VectorSet` is used to make finding the index `O(1)`. The
new utility function may also be useful elsewhere.
Pull Request: https://projects.blender.org/blender/blender/pulls/132272
Instead of storing an optional in the runtime data of each node,
move the field status for the socket to an array in the node tree's
runtime data. This wasn't possible before because selecting nodes
reordered nodes which caused too much cache recomputation.
The benefit is having less geometry-nodes specific data in the
node socket runtime struct, and a slight move to a more data-
oriented storage format.
Pull Request: https://projects.blender.org/blender/blender/pulls/131822
Currently each node's position is stored in the coordinate space of
its parent. To find the location of a node on the canvas, we have to
apply the translation of each of its parents. Also, nodes have hidden
"offset" values used while transforming frame nodes. Together,
those made the system much more complicated than necessary,
and they made the Python API ineffective.
This commit removes usage of the offset values and moves nodes
to be stored in the "global" space of the node canvas. It also resolves
some weird behavior when resizing frame nodes, and fixes a few bugs.
The change is forward compatible, so we still write files with nodes in
the old parent-space format. In 5.0 the conversion when writing can be
removed. The existing Python API also stays the same. A new
"location_absolute" property gives node locations in global space,
and changing the old property also moves the child nodes of frames.
Resolves#92458, #72904.
Pull Request: https://projects.blender.org/blender/blender/pulls/131335
Previously, the data-block dependencies were always detected in
`update_depsgraph` in `MOD_nodes.cc`. This would only be called when something
called `DEG_relations_tag_update` before. We don't want to trigger a depsgraph
rebuild after each operation in the node editor, as that would be expensive.
However, that also meant that we often had to add data-block dependencies that
are not actually used, but might be used if the user changed e.g. a link. A
typical example for that is a object socket that has a default value, but the
socket is also linked.
Now, the dependencies referenced by the node tree are collected by the node tree
update code which runs after all changes. This way we can detect whether the
dependencies have changed. Only if they have changed, a depsgraph rebuild is
triggered. This now allows also taking into account the mute status of nodes and
whether an input is linked.
There are still more things that could be taken into account. Most obviously
whether a node is connected to an output. This can be done later. The most
tricky aspect here is probably that we also have to consider all viewer nodes as
output, because at the time the node runs, it's not known which viewer will
actually be used (which depends on other editors).
This also cleans up some special cases we had for e.g. the scene time node where
we always had to trigger a depsgraph rebuild when it was added/removed because
of its time dependence. This is now part of a more general system.
This fixes#109219.
Pull Request: https://projects.blender.org/blender/blender/pulls/131446
The main goal is to simplify adding support for nested node panels. The patch
makes use of the updated recursive node declarations introduced in
6ffc585fb8.
The main changes are:
* Rewritten node drawing in a way that makes ui design decisions like panel
visibility and margins more explicit. Especially the handling of margins is
much better now imo. Previously, it was very hard to change the margin for
specific cases without accidentally breaking other situations. Now each
possible case has an explicit margin. This needs a few more lines of code but
is much easier to work with.
* Rewritten node drawing in panel (sidebar + material properties) using the new
ways to iterate over the declaration.
* It's possible to add custom layouts at any point in the node declaration now.
This also replaces the need for having a `draw_buttons` callback for panels.
Pull Request: https://projects.blender.org/blender/blender/pulls/128822
This refactors the lifetime analysis of anonymous attributes in geometry nodes.
The refactor has a couple of goals:
* Use a better and simpler abstraction that can be used when building the
lazy-function graph. We currently have a bunch of duplicate code to handle
"field source" and "caller propagation" attributes. This is now unified so
that one only has to worry about one kind of "reference sets".
* Make the abstraction compatible with handling bundles and closures in case we
want to support them in the future. Both types can contain geometries and
fields so they need to be taken into account when determining lifetimes.
* Make more parts independent of the concept of "anonymous attributes". In
theory, there could be more kinds of referenced data whose lifetimes need to
be managed. I don't have any concrete plans for adding any though.
At its core, deterministic anonymous attributes still work the same they have
been since they became deterministic [0]. Even the generated lazy-function graph
is still pretty much or even exactly the same as before.
The patch renames `AnonymousAttributeSet` to the more general
`GeometryNodesReferenceSet` which is more. This also makes more places
independent of the concept of anonymous attributes. Functionally, this still the
same though. It's only used in the internals of geometry nodes nowadays. Most
code just gets an `AttributeFilter` that is based on it.
[0]: https://archive.blender.org/developer/D16858
Pull Request: https://projects.blender.org/blender/blender/pulls/128667
The tricky thing here is that this graph is only generated while geometry nodes
is evaluated and is generally only stored temporarily. To make it accessible via
Python, the accessor method will cause a reevaluation specifically to log the
generated graph.
Previously, the inferencing result was only stored in the socket shape.
However, that was conflicting with experiments where the socket shape and
the field state was not related.
Use snake style naming for all the kernel nodes functions.
Omit kernel prefix in the names since of the using namespace.
Use full forms of the terms
('iter' -> 'iterator', 'ntree' -> 'node_tree', 'rem' -> 'remove', ...).
Pull Request: https://projects.blender.org/blender/blender/pulls/126416
This adds support for attaching gizmos for input values. The goal is to make it
easier for users to set input values intuitively in the 3D viewport.
We went through multiple different possible designs until we settled on the one
implemented here. We picked it for it's flexibility and ease of use when using
geometry node assets. The core principle in the design is that **gizmos are
attached to existing input values instead of being the input value themselves**.
This actually fits the existing concept of gizmos in Blender well, but may be a
bit unintutitive in a node setup at first. The attachment is done using links in
the node editor.
The most basic usage of the node is to link a Value node to the new Linear Gizmo
node. This attaches the gizmo to the input value and allows you to change it
from the 3D view. The attachment is indicated by the gizmo icon in the sockets
which are controlled by a gizmo as well as the back-link (notice the double
link) when the gizmo is active.
The core principle makes it straight forward to control the same node setup from
the 3D view with gizmos, or by manually changing input values, or by driving the
input values procedurally.
If the input value is controlled indirectly by other inputs, it's often possible
to **automatically propagate** the gizmo to the actual input.
Backpropagation does not work for all nodes, although more nodes can be
supported over time.
This patch adds the first three gizmo nodes which cover common use cases:
* **Linear Gizmo**: Creates a gizmo that controls a float or integer value using
a linear movement of e.g. an arrow in the 3D viewport.
* **Dial Gizmo**: Creates a circular gizmo in the 3D viewport that can be
rotated to change the attached angle input.
* **Transform Gizmo**: Creates a simple gizmo for location, rotation and scale.
In the future, more built-in gizmos and potentially the ability for custom
gizmos could be added.
All gizmo nodes have a **Transform** geometry output. Using it is optional but
it is recommended when the gizmo is used to control inputs that affect a
geometry. When it is used, Blender will automatically transform the gizmos
together with the geometry that they control. To achieve this, the output should
be merged with the generated geometry using the *Join Geometry* node. The data
contained in *Transform* output is not visible geometry, but just internal
information that helps Blender to give a better user experience when using
gizmos.
The gizmo nodes have a multi-input socket. This allows **controlling multiple
values** with the same gizmo.
Only a small set of **gizmo shapes** is supported initially. It might be
extended in the future but one goal is to give the gizmos used by different node
group assets a familiar look and feel. A similar constraint exists for
**colors**. Currently, one can choose from a fixed set of colors which can be
modified in the theme settings.
The set of **visible gizmos** is determined by a multiple factors because it's
not really feasible to show all possible gizmos at all times. To see any of the
geometry nodes gizmos, the "Active Modifier" option has to be enabled in the
"Viewport Gizmos" popover. Then all gizmos are drawn for which at least one of
the following is true:
* The gizmo controls an input of the active modifier of the active object.
* The gizmo controls a value in a selected node in an open node editor.
* The gizmo controls a pinned value in an open node editor. Pinning works by
clicking the gizmo icon next to the value.
Pull Request: https://projects.blender.org/blender/blender/pulls/112677
Blender shows invalid links in red in the node editor. However, it's not always
obvious why some links don't work, especially for beginners. This patch adds
additional information for every invalid link on the node that it links to.
The following error messages are added:
* Invalid link because of missing implicit conversions.
* Link cycle in node tree.
* A link from a field to a socket that does not support fields.
* Using the same menu on multiple Menu Switch nodes.
Currently, there are some per tree-type special cases in the link validation code.
In the future, this should be moved to tree type specific callbacks.
Pull Request: https://projects.blender.org/blender/blender/pulls/121976
Move all header file into namespace.
Unnecessary namespaces was removed from implementations file.
Part of forward declarations in header was moved in the top part
of file just to do not have a lot of separate namespaces.
Pull Request: https://projects.blender.org/blender/blender/pulls/121637
To know if link is connected to dangling reroute and can be skipped
as value-less, we need to know if reroute is dangling. This requires
graph traversal. Currently this is done by non-recursive iteration.
But this can lead quadratic complexity for some of the cases.
Other way is to make this linear while cache building.
Pull Request: https://projects.blender.org/blender/blender/pulls/120375
Currently we have some old code from shader/compositor/texture nodes
that stores runtime data during and after evaluation on the node tree
itself. This is meant to be avoided, since the node tree is just meant
to be evaluation _instructions_.
Pull Request: https://projects.blender.org/blender/blender/pulls/118056
It shouldn't be possible to retrieve a mutable interface item from
a const node tree. Unfortunately that means we have to duplicate
the accessor methods. Fortunately they are very small.
The goal of this patch is to allow us to use dynamic node declarations
for various nodes in a future version without breaking forward compatibility.
The same kind of change should be added to Blender 3.6.
The code added here is not supposed to end up in `main`, so it has to be
removed when merging the release branch.
Pull Request: https://projects.blender.org/blender/blender/pulls/113497
In #112326 the socket visibility functions were updated to take the
open/closed state of panels into account for visibility of the socket
icon. However, in "hidden" (collapsed) nodes the panels should be
ignored entirely, drawing all sockets on the root level. This requires
looking at the node flags to determine socket icon visibility, so a
simple method of `bNodeSocket` is not sufficient.
This patch moves the more complex visibility queries for sockets into
`bNode`, where both node and socket flags can be accessed. These should
be used for actual visibility rather than the plain flag accessors on
`bNodeSocket`.
Renamed `is_visible_or_panel_closed` back to just `is_visible`, the
other `is_visible` variant is now integrated in `bNode::is_socket_drawn`.
Pull Request: https://projects.blender.org/blender/blender/pulls/112520
#112019 included open/closed state of the parent panel in socket
visibility calculation. This prevents dragging links, but also disables
other features that should still work, such as drawing links.
A narrower condition is needed for icon visibility vs. general socket
visibility. The cases which use the new `is_icon_visible` condition:
- Drawing socket selection outlines (same as unselected sockets)
- Drawing multi-input sockets (same as unselected sockets)
- `node_find_indicated_socket`, used by a wide range of mouse click
operators, including the link-drag operator that was cause for
#112019.
Cases using the original `is_visible` (true even if parent panel is
collapsed):
- `nodeLinkIsHidden` draws links only when at least one socket is
visible.
- `node_update_basis`, sockets still added to layout even if icon isn't
rendered.
- `node_update_hidden`, panels are ignored for "hidden" nodes, all
sockets are rendered.
- `NODE_OT_link_make` operator for finding "best" sockets to connect.
- `node_link_viewer` finding sockets to connect to a viewer node.
- `get_main_socket` used for insert-on-links (find sockets to splice
into) and some shader previews
- `node_gather_link_searches`, suggestions for adding a new node at the
end of a link.
Pull Request: https://projects.blender.org/blender/blender/pulls/112326
Calling an API function after the node panels patch does not internally
tag the node tree with `NTREE_CHANGED_INTERFACE` any more, because the
node tree is not directly accessible from `bNodeTreeInterface`. Before
node panels the API functions for interfaces could tag the tree directly
for later update consideration, which now requires explicit tagging
calls.
The fix is to add a flag and mutex directly to `bNodeTreeInterface`, so
API methods can tag after updates. This mostly copies runtime data
concepts from `bNodeTree`. The `ensure_interface_cache` method is
equivalent to `ensure_topology_cache` and should be called before
accessing `interface_inputs` and similar cache data.
Pull Request: https://projects.blender.org/blender/blender/pulls/111741
Part 3/3 of #109135, #110272
Switch to new node group interfaces and deprecate old DNA and API.
This completes support for panels in node drawing and in node group
interface declarations in particular.
The new node group interface DNA and RNA code has been added in parts
1 and 2 (#110885, #110952) but has not be enabled yet. This commit
completes the integration by
* enabling the new RNA API
* using the new API in UI
* read/write new interfaces from blend files
* add versioning for backward compatibility
* add forward-compatible writing code to reconstruct old interfaces
All places accessing node group interface declarations should now be
using the new API. A runtime cache has been added that allows simple
linear access to socket inputs and outputs even when a panel hierarchy
is used.
Old DNA has been deprecated and should only be accessed for versioning
(inputs/outputs renamed to inputs_legacy/outputs_legacy to catch
errors). Versioning code ensures both backward and forward
compatibility of existing files.
The API for old interfaces is removed. The new API is very similar but
is defined on the `ntree.interface` instead of the `ntree` directly.
Breaking change notifications and detailed instructions for migrating
will be added.
A python test has been added for the node group API functions. This
includes new functionality such as creating panels and moving items
between different levels.
This patch does not yet contain panel representations in the modifier
UI. This has been tested in a separate branch and will be added with a
later PR (#108565).
Pull Request: https://projects.blender.org/blender/blender/pulls/111348
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.
While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.
Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.
Some directories in `./intern/` have also been excluded:
- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.
An "AUTHORS" file has been added, using the chromium projects authors
file as a template.
Design task: #110784
Ref !110783.
First implementation of node previews in the shader node editor. Using
the same user interface as compositor node previews, most shader nodes
can now be previewed (except group in/output and material output).
This is currently still an experimental feature, as polishing of the
user experience and performance improvements are planned. These will
be easier to do as incremental changes on this implementation.
See #110353 for details on the work that remains to be done and known
limitations.
Implementation notes:
We take advantage of the `RenderResult` available as `ImBuf` images to
store a `Render` for every viewed nested node tree present in a
`SpaceNode`. The computation is initiated at the moment of drawing nodes
overlays.
One render is started for the current nodetree, having a `ViewLayer`
associated with each previewed node. We separate the previewed nodes in
two categories: the shader ones and the non-shader ones.
- For non-shader nodes, we use AOVs which highly speed up the rendering
process by rendering every non-shader nodes at the same time. They are
rendered in the first `ViewLayer`.
- For shader nodes, we render them each in a different `ViewLayer`, by
rerouting the node to the output of the material in the preview scene.
The preview scene takes the same aspect as the Material preview scene,
and the same preview object is used.
At the moment of drawing the node overlay, we take the `Render` of the
viewed node tree and extract the `ImBuf` of the wanted viewlayer/pass
for each previewed node.
Pull Request: https://projects.blender.org/blender/blender/pulls/110065
This feature is going to be replaced with a more thorough refactoring
of the node group interface UI, which has actual node drawing support
and a new API for integration of panels into nodes.
Design task: #109135
Implementation: #110272
Pull Request: https://projects.blender.org/blender/blender/pulls/110803
Move the node previews to the overlay region, atop each node.
It allows nodes to keep the same size when the preview is toggled,
which is more convenient for large nodes and large nodetrees.
The preview has to be drawn from `node_draw_extra_info_panel`
because there could be overlapping between info text and the preview.
When the node is out of the view, it also has to make sure that the
preview is also out of the view before exiting the draw function.
Pull Request: https://projects.blender.org/blender/blender/pulls/108001
The simulation state used by simulation nodes is owned by the modifier. Since a
geometry nodes setup can contain an arbitrary number of simulations, the modifier
has a mapping from `SimulationZoneID` to `SimulationZoneState`. This patch changes
what is used as `SimulationZoneID`.
Previously, the `SimulationZoneID` contained a list of `bNode::identifier` that described
the path from the root node tree to the simulation output node. This works ok in many
cases, but also has a significant problem: The `SimulationZoneID` changes when moving
the simulation zone into or out of a node group. This implies that any of these operations
loses the mapping from zone to simulation state, invalidating the cache or even baked data.
The goal of this patch is to introduce a single-integer ID that identifies a (nested) simulation
zone and is stable even when grouping and un-grouping. The ID should be stable even if the
node group containing the (nested) simulation zone is in a separate linked .blend file and
that linked file is changed.
In the future, the same kind of ID can be used to store e.g. checkpoint/baked/frozen data
in the modifier.
To achieve the described goal, node trees can now store an arbitrary number of nested node
references (an array of `bNestedNodeRef`). Each nested node reference has an ID that is
unique within the current node tree. The node tree does not store the entire path to the
nested node. Instead it only know which group node the nested node is in, and what the
nested node ID of the node is within that group. Grouping and un-grouping operations
have to update the nested node references to keep the IDs stable. Importantly though,
these operations only have to care about the two node groups that are affected. IDs in
higher level node groups remain unchanged by design.
A consequence of this design is that every `bNodeTree` now has a `bNestedNodeRef`
for every (nested) simulation zone. Two instances of the same simulation zone (because
a node group is reused) are referenced by two separate `bNestedNodeRef`. This is
important to keep in mind, because it also means that this solution doesn't scale well if
we wanted to use it to keep stable references to *all* nested nodes. I can't think of a
solution that fulfills the described requirements but scales better with more nodes. For
that reason, this solution should only be used when we want to store data for each
referenced nested node at the top level (like we do for simulations).
This is not a replacement for `ViewerPath` which can store a path to data in a node tree
without changing the node tree. Also `ViewerPath` can contain information like the loop
iteration that should be viewed (#109164). `bNestedNodeRef` can't differentiate between
different iterations of a loop. This also means that simulations can't be used inside of a
loop (loops inside of a simulation work fine though).
When baking, the new stable ID is now written to disk, which means that baked data is
not invalidated by grouping/un-grouping operations. Backward compatibility for baked
data is provided, but only works as long as the simulation zone has not been moved to
a different node group yet. Forward compatibility for the baked data is not provided
(so older versions can't load the data baked with a newer version of Blender).
Pull Request: https://projects.blender.org/blender/blender/pulls/109444