Currently, tree, node and socket types are always freed immediately when the
Python code unregisters them. This is problematic, because there may still be
references to those type pointers in evaluated data owned by potentially various
depsgraphs. It's not possible to change data in these depsgraphs, because they
may be independent from the original data and might be worked on by a separate
thread. So when the type pointers are freed directly, there will be a lot of
dangling pointers in evaluated copies. Since those are used to free the nodes,
there will be a crash when the depsgraph updates. In practice, this does not
happen that often, because typically custom node tree addons are not disabled
while in use. They still used to crash often, but only when Blender exits and
unregisters all types.
The solution is to just keep the typeinfo pointers alive and free them all at
the very end. This obviously has the downside that the list of pointers we need
to keep track of can grow endlessly, however in practice that doesn't really
happen under any normal circumstances.
I'm still getting some other crashes when enabling/disabling Sverchok while
testing, but not entirely reliably and also without this patch (the crash there
happens in RNA code). So some additional work will probably be needed later to
make this work properly in all cases.
Pull Request: https://projects.blender.org/blender/blender/pulls/134360
Currently UI code always has to use char pointers when interacting with
the translation system. This makes benefiting from the use C++ strings
and StringRef more difficult. That means we're leaving some type safety
and performance on the table. This PR adds StringRef overloads to the
translation API functions and removes the few calls to `.c_str()` that
are now unnecessary.
Pull Request: https://projects.blender.org/blender/blender/pulls/133887
Artists often want to quickly switch back and forth between two or more nodes while compositing.
This patch implements two operators `NODE_OT_viewer_shortcut_set` and `NODE_OT_viewer_shortcut_get` that allow users to map a viewer node to a shortcut. For example, pressing `cltr+1` while a node is selected, assigns that node to the shortcut `1`, creates a viewer node if it has none attached and sets that viewer node to active. Pressing `1` will set the active node with shortcut `1` to active.
Shortcuts are saved in DNA to preserve them after saving/loading blend files.
Limitations:
- Only compositor node tree is supported, because shading editor has no viewer node and geometry nodes viewer works differently.
Pull Request: https://projects.blender.org/blender/blender/pulls/123641
Previously, there was a `StringRef.copy` method which would copy the string into
the given buffer. However, it was not defined for the case when the buffer was
too small. It moved the responsibility of making sure the buffer is large enough
to the caller.
Unfortunately, in practice that easily hides bugs in builds without asserts
which don't come up in testing much. Now, the method is replaced with
`StringRef.copy_utf8_truncated` which has much more well defined semantics and
also makes sure that the string remains valid utf-8.
This also renames `unsafe_copy` to `copy_unsafe` to make the naming more similar
to `copy_utf8_truncated`.
Pull Request: https://projects.blender.org/blender/blender/pulls/133677
Since 4cf7fc3b3a (where a storage handling being added) a render layer node never has persist storage data.
And even more, some code of node update do use storage field as temporal variables for a callback so no any data can live forever in this place.
No one copy/initialize/free callback of the node also does not deal with node storage.
And compositor code also don't know about node storage since use different data from a node (id and custom1 fields).
Pull Request: https://projects.blender.org/blender/blender/pulls/132717
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
This makes specifying a legacy type for new node types optional (e.g.
`GEO_NODE_MESH_TO_CURVE`). Instead, only the `idname` is used as a stable
identifier for node types. So there is less redundancy for now.
This change helps with the decentralized definition of nodes and reduces the
number minimum number of files that need to be changed for a new node from 5 to
4. It especially helps when multiple nodes are worked on at the same time,
because the legacy type definition was very prone to have merge conflicts.
For compatibility reasons and because it's still used by existing code, the
`legacy_type` is not removed. All existing nodes keep their current
`legacy_type`. New nodes will receive an auto-incremented legacy type. It's
still necessary to give nodes unique legacy types, because some code checks if
two nodes have the same type by comparing their `legacy_type`. These types only
have to be unique at run-time though. Some randomness is used to avoid depending
on stable generated legacy types accidentally.
Pull Request: https://projects.blender.org/blender/blender/pulls/133044
Previously, the owner-id on localized node trees, like the one created in
`GPU_material_from_nodetree` would have `bNodeTree::owner_id` set, even though
they were independent. The leads to asserts when using `BKE_id_owner_get` on the
localized node tree.
The `node_tree_localize` already took a `ID *new_owner_id` parameter. However,
if it was `nullptr` it was ignored instead actually clearing the `owner_id`.
This patch changes the parameter to `std::optional<ID *> new_owner_id`. Now,
`std::nullopt` means that the value is ignored and when `nullptr` is passed in,
the `owner_id` will be cleared on the localized tree.
Since `node_tree_localize` indirectly uses other functions, the same function
signature change is done in `BKE_libblock_copy_in_lib` and `BKE_id_copy_in_lib`.
The callers have been updated to pass in `nullopt` instead of `nullptr`.
Pull Request: https://projects.blender.org/blender/blender/pulls/133002
Main goals of this refactor:
* Make it more obvious which update function should be used.
* Make it more obvious which parameters are required by using references instead
of pointers.
* Support passing in multiple modified trees instead of just a single one.
No functional changes are expected.
Pull Request: https://projects.blender.org/blender/blender/pulls/132862
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
This removes the second to last usage of `NOD_static_types.hh` which we intend
to remove. A nice benefit is that the idname is now finally more explicit when a
node is registered. Previously it was difficult to search for the definition of
a node in the code when one had only the idname, which is the main identifier
for nodes.
The main change is in `node_type_base`.
Pull Request: https://projects.blender.org/blender/blender/pulls/132815
As part of an effort to remove this header, reducing the need for macro/
include magic and making node definitions more independent, move
the node UI name and description definitions to each node's file.
The UI name, description, and idname are also moved to std::string
instead of char arrays.
Similar to b43e2168e3.
Pull Request: https://projects.blender.org/blender/blender/pulls/132708
Make the type structs non-trivial, use new and delete for allocation and
freeing, and use std::string for most strings they contain. Also use
StringRef instead of char pointers in a few places. Mainly this improves
ergonomics when working with the strings.
Pull Request: https://projects.blender.org/blender/blender/pulls/132750
A followup for 5e7f3e5c84.
Make the NOD_static_types.h file less important by moving `enum_name_legacy`
to be defined in the register function of every node. This helps our gradual transition
away from this file.
Also add a fallback to the node idname so that newly added nodes no longer need
to define the string value.
Pull Request: https://projects.blender.org/blender/blender/pulls/132131
The returned pointer shouldn't be passed to a function expecting
a null terminated C string. Use the StringRef::copy function instead
which is more efficient anyway since it doesn't have to measure the
size of the string again.
This PR improves the animation editor's display of node socket property
animation names, and names from geometry nodes modifier inputs. In both
cases, the names currently displayed are not very useful.
For geometry nodes inputs, the we now look up the name of the the input
rather than just displaying the identifier from the IDProperty name.
For node sockets, we now display the name of the socket instead of just
"Default Value" (which is technically the name of the RNA property).
We also display the label of the node if it's available. We also display
node labels instead of names for node properties.
Pull Request: https://projects.blender.org/blender/blender/pulls/131766
Add a comment that documents the assumption that a node tree can only be
embedded by animatable ID types. At this moment this assumption holds.
`blender::animrig::internal::rebuild_slot_user_cache()` uses this for an
optimisation. It fully skips all non-animatable IDs, and would therefore
also not see any hypothetically animated node tree embedded in a
non-animatable ID type.
Pull Request: https://projects.blender.org/blender/blender/pulls/131844
- Use return values instead of return arguments
- Remove the socket index lookup which was only used once
- Always use the topology cache for node_find_node
- Improve the documentation
- Add a const version of node_find_node
Overall, I think always using the topology cache will give more
predictable performance. Though it may require more cache
rebuilds after the node tree is changed, in practice there are
plenty of other things that require that already. This way, code
that doesn't change the node tree will get better performance
without having to think about the caching.
Pull Request: https://projects.blender.org/blender/blender/pulls/131811
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
Use StringRefNull for all function arguments and return types.
Not a StringRef but StringRefNull since there is still large
interaction with C api so null-termination usually necessary.
If string is expected to be not only empty but also a null then
optional is used. This change depends on #130935.
Pull Request: https://projects.blender.org/blender/blender/pulls/131204
We weren't handling the failure case of `IDP_AddToGroup` when the
property already exists. Arguably this is a bit bad because we're not
recording the type of the second socket with the same name, but we
don't really have the tools to solve that with IDProperties.
NOTE: This also required some changes to Cycles code itself, who is now
directly including `BKE_image.hh` instead of declaring a few prototypes
of these functions in its `blender/utils.h` header (due to C++ functions
names mangling, this was not working anymore).
Pull Request: https://projects.blender.org/blender/blender/pulls/130174
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
This adds a new type of zone to Geometry Nodes that allows executing some nodes
for each element in a geometry.
## Features
* The `Selection` input allows iterating over a subset of elements on the set
domain.
* Fields passed into the input node are available as single values inside of the
zone.
* The input geometry can be split up into separate (completely independent)
geometries for each element (on all domains except face corner).
* New attributes can be created on the input geometry by outputting a single
value from each iteration.
* New geometries can be generated in each iteration.
* All of these geometries are joined to form the final output.
* Attributes from the input geometry are propagated to the output
geometries.
## Evaluation
The evaluation strategy is similar to the one used for repeat zones. Namely, it
dynamically builds a `lazy_function::Graph` once it knows how many iterations
are necessary. It contains a separate node for each iteration. The inputs for
each iteration are hardcoded into the graph. The outputs of each iteration a
passed to a separate lazy-function that reduces all the values down to the final
outputs. This final output can have a huge number of inputs and that is not
ideal for multi-threading yet, but that can still be improved in the future.
## Performance
There is a non-neglilible amount of overhead for each iteration. The overhead is
way larger than the per-element overhead when just doing field evaluation.
Therefore, normal field evaluation should be preferred when possible. That can
partially still be optimized if there is only some number crunching going on in
the zone but that optimization is not implemented yet.
However, processing many small geometries (e.g. each hair of a character
separately) will likely **always be slower** than working on fewer larger
geoemtries. The additional flexibility you get by processing each element
separately comes at the cost that Blender can't optimize the operation as well.
For node groups that need to handle lots of geometry elements, we recommend
trying to design the node setup so that iteration over tiny sub-geometries is
not required.
An opposite point is true as well though. It can be faster to process more
medium sized geometries in parallel than fewer very large geometries because of
more multi-threading opportunities. The exact threshold between tiny, medium and
large geometries depends on a lot of factors though.
Overall, this initial version of the new zone does not implement all
optimization opportunities yet, but the points mentioned above will still hold
true later.
Pull Request: https://projects.blender.org/blender/blender/pulls/127331
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 the ability to customize the default width of a group node that's
created for a node group. This feature works towards the goal of unifying the
features available to built-in nodes and node groups. We often customize the
width of built-in nodes from them to looks slightly better (e.g. to avoid
cut-off labels).
Pull Request: https://projects.blender.org/blender/blender/pulls/126054