When creating a Combine Bundle node using link-drag-search from a
bundle-input-socket, the new node will be initialized to have all the sockets
that linked Separate Bundle nodes have. This uses the same mechanism that's used
for creating closure zones, so it works even if the Separate Bundle node is in
some nested node group.
Pull Request: https://projects.blender.org/blender/blender/pulls/140185
This adds support for specifying structure types on closures. The main immediate
benefit is that this makes it possible to use fields with closures (without
having incorrect warnings in the UI).
A closure zone behaves very similar to a node group with respect to structure
type inferencing. The structure types can be inferenced fully automatically, or
the user can specify them manually on the closure inputs. On the evaluate
closure zone, the user has to specify the structure types of the inputs and
outputs explicitly (or leave them as dynamic).
Working on this, I was a bit surprised that `get_output_socket_shape` depended
on the field state. Is that a left-over? It feels like it shouldn't be necessary
since the socket shape shouldn't depend on field inferencing anymore. I removed
that now and couldn't see a difference yet.
The operator that creates a closure zone from an evaluate closure node copies
the input structure types already. Beyond that, there is no automatic syncing of
the structure types yet. The structure types only affect the UI and not what's
actually done during evaluation.
Pull Request: https://projects.blender.org/blender/blender/pulls/139713
Baking and storing simulation state within loops or closures is not supported.
Previously, attempting to use the bake node or simulation zone in such a zone
would just silently fail. Now there is an error on the node and the bake
settings are grayed out.
Pull Request: https://projects.blender.org/blender/blender/pulls/140041
This adds a new Format String node which simplifies constructing strings from
multiple values. The node takes a format string and a dynamic number of
additional parameters as input. The format string determines how the other
inputs are inserted into the string. Only integer, float and string inputs are
supported for now.
It supports two different format syntaxes:
* Python compatible format syntax which also mostly matches the behavior of the
`fmt` C++ library. Most of this is supported, but there are some small
limitations.
* Syntax of the form `###.##` where each `#` stands for a digit. This is the
syntax that was introduced in #134860.
This node greatly simplifies common string operations which would have required
potentially many nodes before to convert numbers to strings and to concatenate
them. It also makes new conversions possible that were not supported before.
This node can also be used to insert e.g. frame numbers into a file path which
was surprisingly complex before.
This node has special behavior for the name of new inputs. For the purpose of
the node, the name of the inputs must be valid identifiers and it's usually
helpful when they are short. New names are therefore initialized to be single
characters. If possible, the first character of the linked input is used. This
works well when connecting e.g. a Separate Vector/Color node. Otherwise, inputs
are named `a` to `z` by default. If that's not possible, the source socket name
is used instead (converted to be a valid identifier). If that still doesn't
work, the name is made unique using the normal `.001` mechanism except that `_`
instead of `.` is used as separator to make the name a valid identifier.
Python Syntax references:
* Python: https://docs.python.org/3/library/string.html#formatspec
* `fmt`: https://fmt.dev/latest/syntax/
More detailed notes about compatibility with the above syntax specifications:
* Conversion using e.g. `!r` like in Python is not supported (maybe the future).
* Sub-attribute access like `{vector.x}` is not supported (maybe the future).
* Using `%` like in Python is not supported (maybe in future).
* Using `#` for an alternate form is not supported. This might help in the
future to make the syntax compatible with #134860.
* Using `L` like in the `fmt` library is not supported because it depends on the
locale which is not good for determinism.
* Grouping with e.g. thousands separators using e.g. `,` or `_` like in Python
is not supported (maybe in future). Need to think about the locale here too.
* Mixing of unnamed (`{}`) and named (`{x} or {0}`) specifiers is allowed.
However, all unnamed specifiers must come before any named specifier.
The implementation uses the `fmt` library for the actual formatting. However,
the inputs are preprocessed to give us more control over the exact supported
syntax and error messages. The code is already somewhat written so that many
strings could be formatted with the same format but that's not actually used yet
because we don't have string fields yet.
Error messages are propagated using a new mechanism that allows a limited form
of error propagation from multi-functions to the node that evaluates them.
Currently, this only works in fairly limited circumstances, e.g. it does not
work during field evaluation. Since this node is never part of field evaluation
yet, that limitation seems ok, but it's something to work on at some point.
Properly supporting that requires some more changes to propagate enough context
information everywhere. Also showing errors of field evaluation on the field
node itself (instead of on the evaluation node) requires even more work because
our current logging system is not setup to support that yet.
This node comes with a few new requirements for the socket items system: names
must be valid identifiers and they are initialized in a non-trivial way.
Overall, this was fairly straight forward to implement but currently it requires
to adding a bunch of new members to all the accessors that don't really need it.
This is something that we should simplify at some point even if I'm not entirely
sure how yet. The same new requirements used in this node would probably also
exist in a potential future expression node.
Pull Request: https://projects.blender.org/blender/blender/pulls/138860
This mainly results in an error when trying to use the a simulation zone in
a node tool which is not supported yet. It might become supported in the
future though.
Implementation of #127106.
This is just a visual representation of the field/single/grid
status of sockets to make the workflow more intuitive. With
a visual representation for volume grid sockets, volume features
should be unblocked for further development. The structure type
will also be used to distinguish list sockets in the interface.
Group input nodes now have a "Structure Type" option instead of
the existing "Single Value Only". Usually the auto option should be
enough, but in some cases where the inferencing cannot (yet) make
a clear determination, it can be helpful to choose a specific type.
The new visualization and the group input structure type option
are hidden behind a new experimental option for now.
Pull Request: https://projects.blender.org/blender/blender/pulls/134811
This is not something we support currently. Before, the simulation would just
not do anything. Now there is an error message.
In theory, a limited version of that could be supported eventually but it does
not have high priority currently. The tricky aspect of supporting this is that
each simulation has a cache, can be baked etc and we need a persistent identify
for those. That's not possible if simulations can be added and removed
dynamically all the time.
Pull Request: https://projects.blender.org/blender/blender/pulls/139479
This removes redundant labels from various input nodes like the Value, Integer
and Object node.
Design wise, this is mostly straight forward except for two aspects:
* Some input nodes some have a gizmo icon. In this case I just added the gizmo
icon on the same row.
* The checkbox in the Boolean input node should probably still have a label, so
I kept that.
Implementation wise this adds a new function to socket declarations that allows
us to override the draw behavior of individual sockets per node.
Pull Request: https://projects.blender.org/blender/blender/pulls/139432
This function has not python equivalent, using the
returned pointer to write properties seems enough
as equivalent as how is done in python.
Also, this removes the unused `uiItemFloatO` API.
Pull Request: https://projects.blender.org/blender/blender/pulls/139355
This is used as base class for the compute contexts for group and evaluate
closure nodes. Furthermore, in the future this can be used for the compute
context that is passed into field evaluation.
Pull Request: https://projects.blender.org/blender/blender/pulls/139377
How solid/faded the edges of a Grease Pencil stroke is
controlled by the `softness` attribute. This change adds a
node that exposes that attribute, allowing the user to
control it via Geometry Nodes.
Pull Request: https://projects.blender.org/blender/blender/pulls/138939
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
Currently, when using link-drag-search and searching for "Value" shows the bake
node first. This is annoying because it's rarely what one means. It's shown
first because it's a shorter search entry.
This patch reduces the weight of that entry so that the Value node shows up
first.
Pull Request: https://projects.blender.org/blender/blender/pulls/139156
This improves implicit node inputs in multiple ways:
* Fix crash when switching a group input socket type from e.g. vector to
integer, while the default input is set to "position". Now, the default input
type is reset automatically if it's invalid.
* Add Left/Right Handle as possible implicit vector inputs (next to Position and
Normal). Those were the only ones that we used internally that were not
exposed yet.
* When creating a new group input from an existing socket, also initialize the
default input based on the socket. E.g. when grouping a `Set Position` node,
the `Position` input of the group will now also use the position attribute by
default.
In addition to these user-level changes, some internal changes were done too:
* Use unified `NodeDefaultInputType` in node declaration instead of function
pointers which were hard to propagate to node groups.
* Use a new reusable `socket_type_supports_default_input_type` function in rna
to filter the list of possible input items.
Pull Request: https://projects.blender.org/blender/blender/pulls/139139
This converts the public `uiItemFullO` function to an object oriented
API (an `uiLayout::op` overload), matching recents changes in the API.
Changes includes the removal of the paramether `IDProperty *properties`
that seems unused (all places just sets `nullptr`, can be added as last
argument with `nullptr` as default value though), and instead of using a
return paramether the function now returns the pointer to write properties.
Pull Request: https://projects.blender.org/blender/blender/pulls/138961
It's not common for object data to reference it's object type
so name the struct member to make this clear.
Also remove BKE_curve_type_get which is no longer needed.
- "Parameters for custom (OSL-based) Cameras" -> "cameras": lower case
in tooltips.
- "Connect two nodes ... (automatically determined": missing
parenthesis.
- "Join curve... control points are detected(if disabled...": add
missing space.
- "Add Selected to Active Objects Collection" -> "Active Object's":
typo.
- "Duplicate the acive shape key" -> "active": typo.
- "Copy selected points ": remove trailing space.
- "Move cursor" -> "Cursor": title case for operator.
- "Paste text to clipboard" -> "from clipboard": typo.
- "An empty Action considered as both a 'layered' and a 'layered'
Action." -> "is considered as both a 'legacy' and a 'layered'
Action": likely copy-paste error.
- "Target's Z axis will constraint..." -> "will constrain": typo.
- "The layer groups is expanded in the UI" -> "layer group": typo.
- Deprecation warnings: add missing parentheses.
- "... on low poly geometry.Offset rays...": add missing space after
period.
- "... relative to the files directory" -> "... to the file's
directory": typo.
- "The unit multiplier for pixels per meter" -> "The base unit": this
property description was copy and pasted.
- "... beyond the faces UVs..." -> "the faces' UVs: typo.
- "Is tracking data contains ..." -> "Whether the tracking data
contains": grammar.
- "Selected text" -> "Text": title case for prop.
- "The user has been shown the "Online Access" prompt and make a
choice" -> "made a choice": grammar.
- "Glare ": remove trailing space.
- "Don't collapse a curves" -> "Do not collapse curves": grammar.
Some issues reported by Tamar Mebonia.
Pull Request: https://projects.blender.org/blender/blender/pulls/139118
Previously, whenever the zone detection algorithm could not find a result, zones
were just not drawn at all. This can be very confusing because it's not
necessarily obvious that something is wrong in this case.
Now, invalid zones and links that made them invalid have an error.
Note, we can't generally detect the "valid part" of zones when there are invalid
links, because it's ambiguous which links are valid. However, the solution here
is to remember the last valid zones, and to look at which links would invalidate
those. Since the zone-detection results in runtime-only data currently, the
error won't show when reopening the file for now.
Implementation wise, this works by keeping a potentially outdated version of the
last valid zones around, even when the zone detection failed. For that to work,
I had to change some node pointers to node identifiers in the zone structs, so
that it is safe to access them even if the nodes have been removed.
Pull Request: https://projects.blender.org/blender/blender/pulls/139044
"Origin to Geometry" was also affected
With very large meshes (report was about this failing for imported
terrain data), we lack precision in `BKE_mesh_center_median`.
First intuition was to just use doubles, but based on the work done
in !132759 to get a more numerically stable way to compute a mean,
we can use that instead.
So this PR moves `compute_sum` into `blender::array_utils`
and re-uses that for `BKE_mesh_center_median`
Pull Request: https://projects.blender.org/blender/blender/pulls/138813
Previously, the `UserData` and `LocalUserData` classes were only supposed to be
used by the lazy-function system. However, they are generic enough so that they
can also be used by the multi-function system. Therefore, this patch extracts
them into a separate header that can be used in both evaluation systems.
I'm doing this in preparation for being able to pass the geometry nodes logger
to multi-functions, to be able to report errors from there.
Pull Request: https://projects.blender.org/blender/blender/pulls/138861
Previously, whenever a node had a non-trivial storage struct, there would have
to be code for it in `node.cc`. Now there is a general callback that new node
types can use to implement their blend read/write behavior.
Some existing nodes were converted to use this decentralized method. However,
some older nodes can't use it in the same way, because the node types were
introduced before there were node idnames. It's also somewhat hard to reason
about special cases that versioning code might have for these nodes, so they
remain unchanged.
The node callback only writes the non-trivial data, while the main node storage
struct is written automatically by relying on `bNodeType::storagename`. This
simplifies the callback in many cases or makes it unnecessary for trivial types.
Some nodes have specific handling for forward-compatibility. This
forward-compatibility code is kept in `node.cc` for now, because it also affects
the main storage struct and therefore has to be changed before that struct is
written.
Pull Request: https://projects.blender.org/blender/blender/pulls/138722
Previously, it was not possible to switch a menu based on another menu. This
patch adds support for this.
Usually, menu sockets are drawn without the label in nodes currently. Now there
is one exception: the Menu Switch node when it switches another menu. If the
label is not shown, the UI is missing crucial information.
Pull Request: https://projects.blender.org/blender/blender/pulls/138704
Previously, Switch node were using the fallback behavior when they were muted.
That implied that the generated internal link was generally not very useful.
This patch makes the behavior of muted switch nodes explicit. Now the internal
link will always point to the first value input and never to the condition
input. Note, for the Menu Switch node this does not make a difference yet,
because menu sockets are not supported there yet (#138704).
Pull Request: https://projects.blender.org/blender/blender/pulls/138724
This converts the public `uiItemO` function to an object oriented
API (`uiLayout::op`).
Also this rearranges `idname` paramether, since this the only one
required, and to make format similar to `uiItemFullO`
Note: One of the benefits of moving from a public function to class
method is to reduce API usage difference between C++ and Python. In
Python this method is called `UILayout::operator`, however `operator`
is a reserved keyword in C++.
Part of: #117604
Pull Request: https://projects.blender.org/blender/blender/pulls/138776
These are generic properties of grids (not stored in voxels) which are
useful to know in geometry nodes. The transform in particular defines
the voxel size. Background value is used outside of active voxels.
Pull Request: https://projects.blender.org/blender/blender/pulls/138592
This adds a new `DNA_sdna_type_ids.hh` header:
```cpp
namespace blender::dna {
/**
* Each DNA struct has an integer identifier which is unique within a specific
* Blender build, but not necessarily across different builds. The identifier
* can be used to index into `SDNA.structs`.
*/
template<typename T> int sdna_struct_id_get();
/**
* The maximum identifier that will be returned by #sdna_struct_id_get in this
* Blender build.
*/
int sdna_struct_id_get_max();
} // namespace blender::dna
```
The `sdna_struct_id_get` function is used as replacement of
`SDNA_TYPE_FROM_STRUCT` in all places except the DNA defaults system. The
defaults system is C code and therefore can't use the template. There is ongoing
work to replace the defaults system as well though: #134531.
Using this templated function has some benefits over the old approach:
* No need to rely on macros.
* Can use type inferencing in functions like `BLO_write_struct` which avoids
redundancy on the call site. E.g. `BLO_write_struct(writer, ActionStrip,
strip);` can become `BLO_write_struct(writer, strip);` which could even become
`writer.write_struct(strip);`. None of that is implemented as part of this
patch though.
* No need to include the generated `dna_type_offsets.h` file which contains a
huge enum.
Implementation wise, this is done using explicit template instantiations in a
new file generated by `makesdna.cc`: `dna_struct_ids.cc`. The generated file
looks like so:
```cpp
namespace blender::dna {
template<typename T> int sdna_struct_id_get();
int sdna_struct_id_get_max();
int sdna_struct_id_get_max() { return 951; }
}
struct IDPropertyUIData;
template<> int blender:🧬:sdna_struct_id_get<IDPropertyUIData>() { return 1; }
struct IDPropertyUIDataEnumItem;
template<> int blender:🧬:sdna_struct_id_get<IDPropertyUIDataEnumItem>() { return 2; }
```
I tried using static variables instead of separate functions, but I didn't
manage to link it properly. Not quite sure yet if that's an actual limitation or
if I was just missing something.
Pull Request: https://projects.blender.org/blender/blender/pulls/138706
Previously, nodes which had their own special internal-links-behavior were
hardcoded in node tree update code. Now that is decentralized so that more nodes
can use this functionality without leaking special cases into general code.
Pull Request: https://projects.blender.org/blender/blender/pulls/138712
Remove the addition of the position attribute from the default
"init data" callback where we don't know the desired number
of points. Add it in the other functions that add the data-block
(except the version that purposefully doesn't add attributes).
Pull Request: https://projects.blender.org/blender/blender/pulls/138697
This converts the public `uiItemFullR` function to an object oriented
API (an overload of `uiLayout::prop`), matching the python API.
This reduces the difference between the C++ API with the python version,
its also helps while converting code from python to C++ code (or vice-versa),
making it almost seamless.
Part of: #117604
Pull Request: https://projects.blender.org/blender/blender/pulls/138683
This converts the public `uiItemR` function to an object oriented
API (`uiLayout::prop`), matching the python API.
This reduces the difference between the C++ API with the python version,
its also helps while converting code from python to C++ code (or vice-versa),
making it almost seamless.
Part of: #117604
Pull Request: https://projects.blender.org/blender/blender/pulls/138617
This converts the public `uiItemL` function to an object oriented
API (`uiLayout::label`), matching the python API.
This reduces the difference between the C++ API with the python version,
its also helps while converting code from python to C++ code (or vice-versa),
making it almost seamless.
Part of: #117604
Pull Request: https://projects.blender.org/blender/blender/pulls/138608
This patch adds a new `BLI_mutex.hh` header which adds `blender::Mutex` as alias
for either `tbb::mutex` or `std::mutex` depending on whether TBB is enabled.
Description copied from the patch:
```
/**
* blender::Mutex should be used as the default mutex in Blender. It implements a subset of the API
* of std::mutex but has overall better guaranteed properties. It can be used with RAII helpers
* like std::lock_guard. However, it is not compatible with e.g. std::condition_variable. So one
* still has to use std::mutex for that case.
*
* The mutex provided by TBB has these properties:
* - It's as fast as a spin-lock in the non-contended case, i.e. when no other thread is trying to
* lock the mutex at the same time.
* - In the contended case, it spins a couple of times but then blocks to avoid draining system
* resources by spinning for a long time.
* - It's only 1 byte large, compared to e.g. 40 bytes when using the std::mutex of GCC. This makes
* it more feasible to have many smaller mutexes which can improve scalability of algorithms
* compared to using fewer larger mutexes. Also it just reduces "memory slop" across Blender.
* - It is *not* a fair mutex, i.e. it's not guaranteed that a thread will ever be able to lock the
* mutex when there are always more than one threads that try to lock it. In the majority of
* cases, using a fair mutex just causes extra overhead without any benefit. std::mutex is not
* guaranteed to be fair either.
*/
```
The performance benchmark suggests that the impact is negilible in almost
all cases. The only benchmarks that show interesting behavior are the once
testing foreach zones in Geometry Nodes. These tests are explicitly testing
overhead, which I still have to reduce over time. So it's not unexpected that
changing the mutex has an impact there. What's interesting is that on macos the
performance improves a lot while on linux it gets worse. Since that overhead
should eventually be removed almost entirely, I don't really consider that
blocking.
Links:
* Documentation of different mutex flavors in TBB:
https://www.intel.com/content/www/us/en/docs/onetbb/developer-guide-api-reference/2021-12/mutex-flavors.html
* Older implementation of a similar mutex by me:
https://archive.blender.org/developer/differential/0016/0016711/index.html
* Interesting read regarding how a mutex can be this small:
https://webkit.org/blog/6161/locking-in-webkit/
Pull Request: https://projects.blender.org/blender/blender/pulls/138370
The special case that just returns a span was incorrect on the point
domain. It shouldn't apply in that case since the input indices are
meant to be curve indices.
Pull Request: https://projects.blender.org/blender/blender/pulls/138506
OpenVDB has a voxel size limit defined by the determinant of the grid
transform, which is equivalent to a uniform voxel size of
`sqrt3(3e-15) ~= 1.44e-5`.
The `mesh_to_density_grid` function was using an arbitrary threshold of
`1.0e-5` for the uniform voxel size.
In this case the voxel size is `~1.343e-5` so it passes the Blender
threshold but crashes in OpenVDB.
This fix adds some convenience functions to check for valid grid voxel
size and transform based on the same determinant metric. This is now
employed consistently in the mesh_to_density_grid, mesh_to_sdf_grid, and
points_to_sdf_grid functions to avoid exceptions in OpenVDB.
MOD_volume_to_mesh, node_geo_volume_to_mesh, BKE_mesh_remesh_voxel have
not been modified, since they have their own error checks with larger
thresholds.
Pull Request: https://projects.blender.org/blender/blender/pulls/138481
The "Active Element" node would return early if the mode was
not `OB_MODE_EDIT`.
For Grease Pencil, we want to be able to query the active layer index
from any mode.
This changes the logic to only return early for the `Point`, `Edge`,
and `Face` element if the mode is not edit mode.
Pull Request: https://projects.blender.org/blender/blender/pulls/138491