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
Previously, we had shown link errors on the target node as part of the node
warning system. While better than not showing any information about invalid
links (as was the state before that), it's still not ideal because it's easy to
miss when just looking at the link.
This patch adds an error icon in the middle of the invalid link. When hovering
over it, it shows the error text. When the middle of the link is not in view but
part of the link is, then the error icon will also stay visible.
Pull Request: https://projects.blender.org/blender/blender/pulls/138529
The group output node is updated as part of the topology cache.
When there are multiple group output nodes the first one with an "active"
flag is picked. However, if no group output is flagged this will leave
the group output unchanged in the cache, even if that node has been deleted.
Always initialize the group output runtime cache to null to avoid invalid
pointers.
Pull Request: https://projects.blender.org/blender/blender/pulls/136436
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
This uses the following accessor methods in more places in more places:
`is_group()`, `is_group_input()`, `is_group_output()`, `is_muted()`,
`is_frame()` and `is_reroute()`.
This results in simpler code and reduces the use of `bNode.type_legacy`.
Pull Request: https://projects.blender.org/blender/blender/pulls/132899
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
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
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
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
For historical reasons, the `multi_input_socket_index` was actually reversed
(large index comes first). This patch renames it to `multi_input_sort_id` and
adds a comment. This new name makes it less confusing that the id is reversed.
Pull Request: https://projects.blender.org/blender/blender/pulls/119652
Previously, it was only possible to bake all simulations at once. This is great
for simple use-cases that, but in more complex setups one can have independent
simulations that should also be baked independently. This patch allows baking
individual simulation zones.
Furthermore, each simulation zone can now also have its own bake path and
simulation frame range. By default the simulation frame range is the scene frame
range, but it can also be customized on the scene or simulation zone level. The
bake path is generated based on the modifier bake path by default, but can be
set to another absolute or relative (to the .blend file) path.
The timeline drawing has been modified as well to be able to show more information
in the case when some simulations are baked and others are not. Instead of showing
a line for every simulation, it shows a condensed view of the important information
using at most two lines:
Is something baked? Is something valid or invalid? Also see #112232.
Pull Request: https://projects.blender.org/blender/blender/pulls/112723
The goal is to reduce redundancy by abstracting over the different types of node
tree zones. This makes it easier to add new zone types and makes the intend of
code more clear. For example, now it is more obvious what code deals with zones
in general and what does simulation specific things.
Pull Request: https://projects.blender.org/blender/blender/pulls/112531
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.
This adds support for running a set of nodes repeatedly. The number
of iterations can be controlled dynamically as an input of the repeat
zone. The repeat zone can be added in via the search or from the
Add > Utilities menu.
The main use case is to replace long repetitive node chains with a more
flexible alternative. Technically, repeat zones can also be used for
many other use cases. However, due to their serial nature, performance
is very sub-optimal when they are used to solve problems that could
be processed in parallel. Better solutions for such use cases will
be worked on separately.
Repeat zones are similar to simulation zones. The major difference is
that they have no concept of time and are always evaluated entirely in
the current frame, while in simulations only a single iteration is
evaluated per frame.
Stopping the repetition early using a dynamic condition is not yet
supported. "Break" functionality can be implemented manually using
Switch nodes in the loop for now. It's likely that this functionality
will be built into the repeat zone in the future.
For now, things are kept more simple.
Remaining Todos after this first version:
* Improve socket inspection and viewer node support. Currently, only
the first iteration is taken into account for socket inspection
and the viewer.
* Make loop evaluation more lazy. Currently, the evaluation is eager,
meaning that it evaluates some nodes even though their output may not
be required.
Pull Request: https://projects.blender.org/blender/blender/pulls/109164
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
The `logically_linked_sockets` runtime data of sockets is only initialized
for inputs. This patch also initializes it for output sockets through
the inversion the inputs logically_linked_sockets structure.
Pull Request: https://projects.blender.org/blender/blender/pulls/109249
A lot of files were missing copyright field in the header and
the Blender Foundation contributed to them in a sense of bug
fixing and general maintenance.
This change makes it explicit that those files are at least
partially copyrighted by the Blender Foundation.
Note that this does not make it so the Blender Foundation is
the only holder of the copyright in those files, and developers
who do not have a signed contract with the foundation still
hold the copyright as well.
Another aspect of this change is using SPDX format for the
header. We already used it for the license specification,
and now we state it for the copyright as well, following the
FAQ:
https://reuse.software/faq/
See: https://projects.blender.org/blender/blender/issues/103343
Changes:
1. Added `BKE_node.hh` file. New file includes old one.
2. Functions moved to new file. Redundant `(void)`, `struct` are removed.
3. All cpp includes replaced from `.h` on `.hh`.
4. Everything in `BKE_node.hh` is on `blender::bke` namespace.
5. All implementation functions moved in namespace.
6. Function names (`BKE_node_*`) changed to `blender::bke::node_*`.
7. `eNodeSizePreset` now is a class, with renamed items.
Pull Request: https://projects.blender.org/blender/blender/pulls/107790
This adds support for building simulations with geometry nodes. A new
`Simulation Input` and `Simulation Output` node allow maintaining a
simulation state across multiple frames. Together these two nodes form
a `simulation zone` which contains all the nodes that update the simulation
state from one frame to the next.
A new simulation zone can be added via the menu
(`Simulation > Simulation Zone`) or with the node add search.
The simulation state contains a geometry by default. However, it is possible
to add multiple geometry sockets as well as other socket types. Currently,
field inputs are evaluated and stored for the preceding geometry socket in
the order that the sockets are shown. Simulation state items can be added
by linking one of the empty sockets to something else. In the sidebar, there
is a new panel that allows adding, removing and reordering these sockets.
The simulation nodes behave as follows:
* On the first frame, the inputs of the `Simulation Input` node are evaluated
to initialize the simulation state. In later frames these sockets are not
evaluated anymore. The `Delta Time` at the first frame is zero, but the
simulation zone is still evaluated.
* On every next frame, the `Simulation Input` node outputs the simulation
state of the previous frame. Nodes in the simulation zone can edit that
data in arbitrary ways, also taking into account the `Delta Time`. The new
simulation state has to be passed to the `Simulation Output` node where it
is cached and forwarded.
* On a frame that is already cached or baked, the nodes in the simulation
zone are not evaluated, because the `Simulation Output` node can return
the previously cached data directly.
It is not allowed to connect sockets from inside the simulation zone to the
outside without going through the `Simulation Output` node. This is a necessary
restriction to make caching and sub-frame interpolation work. Links can go into
the simulation zone without problems though.
Anonymous attributes are not propagated by the simulation nodes unless they
are explicitly stored in the simulation state. This is unfortunate, but
currently there is no practical and reliable alternative. The core problem
is detecting which anonymous attributes will be required for the simulation
and afterwards. While we can detect this for the current evaluation, we can't
look into the future in time to see what data will be necessary. We intend to
make it easier to explicitly pass data through a simulation in the future,
even if the simulation is in a nested node group.
There is a new `Simulation Nodes` panel in the physics tab in the properties
editor. It allows baking all simulation zones on the selected objects. The
baking options are intentially kept at a minimum for this MVP. More features
for simulation baking as well as baking in general can be expected to be added
separately.
All baked data is stored on disk in a folder next to the .blend file. #106937
describes how baking is implemented in more detail. Volumes can not be baked
yet and materials are lost during baking for now. Packing the baked data into
the .blend file is not yet supported.
The timeline indicates which frames are currently cached, baked or cached but
invalidated by user-changes.
Simulation input and output nodes are internally linked together by their
`bNode.identifier` which stays the same even if the node name changes. They
are generally added and removed together. However, there are still cases where
"dangling" simulation nodes can be created currently. Those generally don't
cause harm, but would be nice to avoid this in more cases in the future.
Co-authored-by: Hans Goudey <h.goudey@me.com>
Co-authored-by: Lukas Tönne <lukas@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/104924
Since internal links are only runtime data, we have the flexibility to
allocating every link individually. Instead we can store links directly
in the node runtime vector. This allows avoiding many small allocations
when copying and changing node trees.
In the future we could use a smaller type like a pair of sockets
instead of `bNodeLink` to save memory.
Differential Revision: https://developer.blender.org/D16960
Previously, the code tried to keep node groups working even if some of
their input/output sockets had undefined type. This caused some
complexity with no benefit because not all places outside of this file
would handle the case correctly. Now node groups with undefined
interface sockets are disabled and have to be fixed manually before
they work again.
Undefined interface sockets are mostly caused by invalid Python
API usage and incomplete forward compatibility (e.g. when newer
versions introduce new socket types that the older version does
not know).
Add `bNode::index()` to allow accessing node indices directly without
manually de-referencing the runtime struct. Also adds some asserts to
make sure the access is valid and to check the nodes runtime vector.
Eagerly maintain the node's index in the tree so it can be accessed
without relying on the topology cache.
Differential Revision: https://developer.blender.org/D16683
This patch adds an integer identifier to nodes that doesn't change when
the node name changes. This identifier can be used by different systems
to reference a node. This may be important to store caches and simulation
states per node, because otherwise those would always be invalidated
when a node name changes.
Additionally, this kind of identifier could make some things more efficient,
because with it an integer is enough to identify a node and one does not
have to store the node name.
I observed a 10% improvement in evaluation time in a file with an extreme
number of simple math nodes, due to reduced logging overhead-- from
0.226s to 0.205s.
Differential Revision: https://developer.blender.org/D15775
This allows for optimizations because one does not have to iterate
over all nodes anymore to find all nodes within a frame.
Differential Revision: https://developer.blender.org/D16106
This was essentially a use-after-free issue. When a geometry nodes
group changes it has to be preprocessed again before it can be evaluated.
This part was working, the issue was that parent node groups have to be
preprocessed as well, which was missing. The lazy-function graph cached
on the parent node group was still referencing data that was freed when
the child group changed.
Now the depsgraph makes sure that all relevant geometry node groups are
preprocessed again after a change.
This issue was found by Simon Thommes.
This refactors the geometry nodes evaluation system. No changes for the
user are expected. At a high level the goals are:
* Support using geometry nodes outside of the geometry nodes modifier.
* Support using the evaluator infrastructure for other purposes like field evaluation.
* Support more nodes, especially when many of them are disabled behind switch nodes.
* Support doing preprocessing on node groups.
For more details see T98492.
There are fairly detailed comments in the code, but here is a high level overview
for how it works now:
* There is a new "lazy-function" system. It is similar in spirit to the multi-function
system but with different goals. Instead of optimizing throughput for highly
parallelizable work, this system is designed to compute only the data that is actually
necessary. What data is necessary can be determined dynamically during evaluation.
Many lazy-functions can be composed in a graph to form a new lazy-function, which can
again be used in a graph etc.
* Each geometry node group is converted into a lazy-function graph prior to evaluation.
To evaluate geometry nodes, one then just has to evaluate that graph. Node groups are
no longer inlined into their parents.
Next steps for the evaluation system is to reduce the use of threads in some situations
to avoid overhead. Many small node groups don't benefit from multi-threading at all.
This is much easier to do now because not everything has to be inlined in one huge
node tree anymore.
Differential Revision: https://developer.blender.org/D15914
The purpose of `NodeTreeRef` was to speed up various queries on a read-only
`bNodeTree`. Not that we have runtime data in nodes and sockets, we can also
store the result of some queries there. This has some benefits:
* No need for a read-only separate node tree data structure which increased
complexity.
* Makes it easier to reuse cached queries in more parts of Blender that can
benefit from it.
A downside is that we loose some type safety that we got by having different
types for input and output sockets, as well as internal and non-internal links.
This patch also refactors `DerivedNodeTree` so that it does not use
`NodeTreeRef` anymore, but uses `bNodeTree` directly instead.
To provide a convenient API (that is also close to what `NodeTreeRef` has), a
new approach is implemented: `bNodeTree`, `bNode`, `bNodeSocket` and `bNodeLink`
now have C++ methods declared in `DNA_node_types.h` which are implemented in
`BKE_node_runtime.hh`. To make this work, `makesdna` now skips c++ sections when
parsing dna header files.
No user visible changes are expected.
Differential Revision: https://developer.blender.org/D15491