Commit Graph

168 Commits

Author SHA1 Message Date
499c24ce75 BLI: add slice method to index mask and generic span 2021-11-24 17:49:33 +01:00
47276b8470 Geometry Nodes: reduce overhead when processing single values
Currently the geometry nodes evaluator always stores a field for every
type that supports it, even if it is just a single value. This results in a lot
of overhead when there are many sockets that just contain a single
value, which is often the case.

This introduces a new `ValueOrField<T>` type that is used by the geometry
nodes evaluator. Now a field will only be created when it is actually
necessary. See D13307 for more details. In extrem cases this can speed
up the evaluation 2-3x (those cases are probably never hit in practice
though, but it's good to get rid of unnecessary overhead nevertheless).

Differential Revision: https://developer.blender.org/D13307
2021-11-23 14:49:26 +01:00
c850189adf Cleanup: make naming more consistent 2021-11-22 09:48:36 +01:00
873f6148ad Functions: remove test for dynamic name
This was broken in rB6ee2abde82ef121cd6e927995053ac33afdbb438.
2021-11-21 13:08:23 +01:00
940e6525c7 Functions: fix compile error in tests 2021-11-21 13:06:05 +01:00
15011e0b70 Functions: use static string for parameter names
The idea behind this change is the same as in
rB6ee2abde82ef121cd6e927995053ac33afdbb438.

A `MultiFunction::debug_parameter_name` method could be
added separately when necessary.
2021-11-21 12:57:34 +01:00
6ee2abde82 Functions: use static names for multi-functions
Previously, the function names were stored in `std::string` and were often
created dynamically (especially when the function just output a constant).
This resulted in a lot of overhead.

Now the function name is just a `const char *` that should be statically
allocated. This is good enough for the majority of cases. If a multi-function
needs a more dynamic name, it can override the `MultiFunction::debug_name`
method.

In my test file with >400,000 simple math nodes, the execution time improves from
3s to 1s.
2021-11-21 12:48:07 +01:00
c3422c48ad Cleanup: remove dummy multi function 2021-11-17 12:33:18 +01:00
4c988eb3e1 Fix error with makefiles compilation
Use 'template' keyword to treat 'is' as a dependent template name
2021-11-16 20:46:33 -03:00
d4c868da9f Geometry Nodes: refactor virtual array system
Goals of this refactor:
* Simplify creating virtual arrays.
* Simplify passing virtual arrays around.
* Simplify converting between typed and generic virtual arrays.
* Reduce memory allocations.

As a quick reminder, a virtual arrays is a data structure that behaves like an
array (i.e. it can be accessed using an index). However, it may not actually
be stored as array internally. The two most important implementations
of virtual arrays are those that correspond to an actual plain array and those
that have the same value for every index. However, many more
implementations exist for various reasons (interfacing with legacy attributes,
unified iterator over all points in multiple splines, ...).

With this refactor the core types (`VArray`, `GVArray`, `VMutableArray` and
`GVMutableArray`) can be used like "normal values". They typically live
on the stack. Before, they were usually inside a `std::unique_ptr`. This makes
passing them around much easier. Creation of new virtual arrays is also
much simpler now due to some constructors. Memory allocations are
reduced by making use of small object optimization inside the core types.

Previously, `VArray` was a class with virtual methods that had to be overridden
to change the behavior of a the virtual array. Now,`VArray` has a fixed size
and has no virtual methods. Instead it contains a `VArrayImpl` that is
similar to the old `VArray`. `VArrayImpl` should rarely ever be used directly,
unless a new virtual array implementation is added.

To support the small object optimization for many `VArrayImpl` classes,
a new `blender::Any` type is added. It is similar to `std::any` with two
additional features. It has an adjustable inline buffer size and alignment.
The inline buffer size of `std::any` can't be relied on and is usually too
small for our use case here. Furthermore, `blender::Any` can store
additional user-defined type information without increasing the
stack size.

Differential Revision: https://developer.blender.org/D12986
2021-11-16 10:16:30 +01:00
fb4b737518 CMake: add missing headers to CMake lists 2021-11-08 17:00:36 +11:00
fd477e738d Geometry Nodes: remove reference to anonymous attributes in tooltips
This changes socket inspection for fields according to T91881.

Differential Revision: https://developer.blender.org/D13006
2021-10-26 15:32:01 +02:00
cc388651eb Fix T92327: use default value when field is passed into data socket
Previously, the computed value passed into the data socket could depend
on the actual field a bit. However, given that the link is marked as invalid
in the ui, the user should not depend on this behavior.
Using a default value is consistent with other cases when there are
invalid links.
2021-10-24 17:53:19 +02:00
40c3b8836b Geometry Nodes: Make Random ID a builtin attribute, remove sockets
In order to address feedback that the "Stable ID" was not easy enough
to use, remove the "Stable ID" output from the distribution node and
the input from the instance on points node. Instead, the nodes write
or read a builtin named attribute called `id`. In the future we may
add more attributes like `edge_id` and `face_id`.

The downside is that more behavior is invisible, which is les
expected now that most attributes are passed around with node links.
This behavior will have to be explained in the manual.

The random value node's "ID" input that had an implicit index input
is converted to a special implicit input that uses the `id` attribute
if possible, but otherwise defaults to the index. There is no way to
tell in the UI which it uses, except by knowing that rule and checking
in the spreadsheet for the id attribute.

Because it isn't always possible to create stable randomness, this
attribute does not always exist, and it will be possible to remove it
when we have the attribute remove node back, to improve performance.

Differential Revision: https://developer.blender.org/D12903
2021-10-20 10:54:54 -05:00
967fec6883 Cleanup: sort cmake file lists 2021-10-20 09:17:46 +11:00
a3457704fb Geometry Nodes: De-duplicate index input nodes during evaluation
We do this in other nodes to reduce overhead of using the same node more
than once. I don't think it will make a difference with index nodes
currently, but at least it's consistent.
2021-10-18 20:13:37 -05:00
eb0d216dc1 Geometry Nodes: decouple multi-function lifetimes from modifier
Previously, some multi-functions were allocated in a resource scope.
This was fine as long as the multi-functions were only needed during
the current evaluation of the node tree. However, now cases arise
that require the multi-functions to be alive after the modifier is finished.
For example, we want to evaluate fields created with geometry nodes
outside of geometry nodes.

To make this work, `std::shared_ptr` has to be used in a few more places.
Realistically, this shouldn't have a noticable impact on performance.
If this does become a bottleneck in the future, we can think about ways
to make this work without using `shared_ptr` for multi-functions that
are only used once.
2021-10-18 11:46:21 +02:00
b42ce0c54c Functions: Generic array data structure
Sometimes it's useful to pass around a set of values with a generic
type. The virtual array data structures allow this, but they don't
have logical ownership. My initial use case for this is as a return
type for the functions that interpolate curve attributes to evaluated
points, but a need for this data structure has come up in a few other
places as well. It also reduced the need for templates.

Differential Revision: https://developer.blender.org/D11103
2021-10-14 11:06:18 -05:00
2b66b372bc Cleanup: use doxygen sections 2021-10-05 11:10:25 +11:00
64d07ffcc3 Cleanup: move methods out of field classes
This makes it easier to scan through the classes and simplifies
testing the compile time impact of having these methods in the header.
2021-10-03 16:47:54 +02:00
960b21e1d7 Cleanup: sort cmake file lists 2021-09-29 07:30:34 +10:00
d046a1f2fa Functions: fail early when multi-function throws an exception
Multi-functions are not allowed to throw exceptions that are not
caught in the same multi-function. Previously, it was difficult to
backtrack a crash to a previously thrown exception.
2021-09-26 23:28:14 +02:00
1cd8a438bb Cleanup: simplify field evaluation 2021-09-26 23:28:14 +02:00
88a2b054da Fix T91732: crash in Set Position node on empty mesh 2021-09-26 23:28:14 +02:00
90b410fe74 Fix: field evaluation crash when the domain size is zero 2021-09-24 16:42:20 +02:00
95ec6e4dd3 Geometry Nodes: make index field more reusable
Some inputs will be the index field implicitly, so we want this
class to be available outside of `node_geo_input_index.cc`.
2021-09-24 16:03:07 +02:00
bd1c4a781f Geometry Nodes: fix evaluating field to span 2021-09-22 18:45:11 +02:00
3c1e75a230 Functions: make asserts more correct
It is valid to e.g. copy construct an integer in the same place,
because it is a trivial type. It does not work for types like std::string.

This fixes a crash reported in D12584 where it would copy a buffer
into itself. We should probably also avoid doing this copy alltogether
but that can be done separately.
2021-09-21 17:51:15 +02:00
9e939a614e Functions: Fix incorrect assert for unused output
Since the variable for an output parameter can be null,
it is incorrect to use it later on in a reference.
2021-09-20 20:22:52 -05:00
fc4f82d200 Geometry Nodes: support Noise Texture node
This makes the Noise Texture node available in geometry nodes.
It should behave the same as in shader node, with the exception
that it does not have an implicit position input yet. That will
be added separately.

Differential Revision: https://developer.blender.org/D12467
2021-09-20 13:12:25 +02:00
e6ca054590 Geometry Nodes: multi threaded field evaluation
This adds a new `ParallelMultiFunction` which wraps another multi-function
and evaluates it with multiple threads. The speeds up field evaluation
quite a bit (the effect is most noticeable when the number of evaluations
and the field is large).

There are still other single-threaded performance bottlenecks in field
evaluation that will need to be solved separately. Most notably here
is the process of copying the computed data into the position attribute
in the Set Position node.

Differential Revision: https://developer.blender.org/D12457
2021-09-15 11:02:39 +02:00
dee0b56b92 Cleanup: simplify resource scope methods
Previously, a debug name had to be passed to all methods
that added a resource to the `ResourceScope`. The idea was
that this would make it easier to find certain bugs. In reality
I never found this to be useful, and it was mostly annoying.
The thing is, something that is in a resource scope never leaks
(unless the resource scope is not destructed of course).

Removing the name parameter makes the structure easier to use.
2021-09-14 16:08:09 +02:00
fd60f6713a Functions: support optional outputs in multi-function
Sometimes not all outputs of a multi-function are required by the
caller. In those cases it would be a waste of compute resources
to calculate the unused values anyway. Now, the caller of a
multi-function can specify when a specific output is not used.
The called function can check if an output is unused and may
ignore it. Multi-functions can still computed unused outputs as
before if they don't want to check if a specific output is unused.

The multi-function procedure system has been updated to support
ignored outputs in call instructions. An ignored output just has no
variable assigned to it.

The field system has been updated to generate a multi-function
procedure where unused outputs are ignored.
2021-09-14 14:52:44 +02:00
b777df8080 Fix: fix equality operator for fields
Instead of comparing the referenced field node by pointer,
compare the nodes directly instead. This is important
because different field nodes might be the same semantically.
2021-09-13 13:09:18 +02:00
2aa7edbe6b Cleanup: spelling 2021-09-12 19:51:16 +10:00
4e78b89e48 Geometry Nodes: add field support for socket inspection
Since fields were committed to master, socket inspection did
not work correctly for all socket types anymore. Now the same
functionality as before is back. Furthermore, fields that depend
on some input will now show the inputs in the socket inspection.

I added support for evaluating constant fields more immediately.
This has the benefit that the same constant field is not evaluated
more than once. It also helps with making the field independent
of the multi-functions that it uses. We might still want to change
the ownership handling for the multi-functions of nodes a bit,
but that can be done separately.

Differential Revision: https://developer.blender.org/D12444
2021-09-11 13:05:20 +02:00
166c8be7ac Cleanup: use nullptr 2021-09-11 12:41:46 +02:00
aeeffb935e Functions: store cursors to previous instructions
Now an instruction knows the cursors where it is inserted instead
of just the instruction that references it. This has two benefits:
* An instruction knows when it is the entry instruction.
* The cursor can contain more information, e.g. if it is linked to the
  true or false branch of a branch instruction.

  This also simplifies updating the procedure in future optimization
  passes.
2021-09-11 11:43:59 +02:00
45c44a5b5b Fix compiler warnings about virtual functions but non-virtual destructor 2021-09-09 17:11:01 +02:00
bf47fb40fd Geometry Nodes: fields and anonymous attributes
This implements the initial core framework for fields and anonymous
attributes (also see T91274).

The new functionality is hidden behind the "Geometry Nodes Fields"
feature flag. When enabled in the user preferences, the following
new nodes become available: `Position`, `Index`, `Normal`,
`Set Position` and `Attribute Capture`.

Socket inspection has not been updated to work with fields yet.

Besides these changes at the user level, this patch contains the
ground work for:
* building and evaluating fields at run-time (`FN_fields.hh`) and
* creating and accessing anonymous attributes on geometry
  (`BKE_anonymous_attribute.h`).

For evaluating fields we use a new so called multi-function procedure
(`FN_multi_function_procedure.hh`). It allows composing multi-functions
in arbitrary ways and supports efficient evaluation as is required by
fields. See `FN_multi_function_procedure.hh` for more details on how
this evaluation mechanism can be used.

A new `AttributeIDRef` has been added which allows handling named
and anonymous attributes in the same way in many places.

Hans and I worked on this patch together.

Differential Revision: https://developer.blender.org/D12414
2021-09-09 12:54:20 +02:00
0081200812 Functions: remove multi-function network
The multi-function network system was able to compose multiple
multi-functions into a new one and to evaluate that efficiently.
This functionality was heavily used by the particle nodes prototype
a year ago. However, since then we only used multi-functions
without the need to compose them in geometry nodes.

The upcoming "fields" in geometry nodes will need a way to
compose multi-functions again. Unfortunately, the code removed
in this commit was not ideal for this different kind of function
composition. I've been working on an alternative that will be added
separately when it becomes needed.

I've had to update all the function nodes, because their interface
depended on the multi-function network data structure a bit.
The actual multi-function implementations are still the same though.
2021-08-20 13:14:39 +02:00
d217b34214 Functions: add utility methods to parameter builder 2021-08-20 11:48:31 +02:00
fd51b05a02 Functions: add clear method to vector array 2021-08-20 11:48:31 +02:00
8edb2222ae Cleanup: simplify subclassing CPPType
`CPPType` can wrap any C++ type so that code can work
with the wrapped type in a generic way. The goal of subclassing
`CPPType` is to provide additional methods for some types.
For example, the `CPPType` for `Array<int>` could have a `.element_type()`
method that returns the `CPPType` for `int`.
2021-08-02 12:44:17 +02:00
93eb460dd0 Cleanup: clang-format (re-run after v12 version bump) 2021-07-30 16:19:19 +10:00
828c66f393 Cleanup: spelling in comments 2021-07-26 12:32:42 +10:00
24a77745a4 Functions: add utility to create string from value of generic type 2021-07-05 13:02:16 +02:00
aa112dc77c Cleanup: spelling 2021-07-01 11:16:25 +10:00
7d281a4f7d Functions: improve CPPType
* Reduce code duplication.
* Give methods more standardized names (e.g. `move_to_initialized` -> `move_assign`).
* Support wrapping arbitrary C++ types, even those that e.g. are not copyable.
2021-06-28 13:16:32 +02:00
4b9ff3cd42 Cleanup: comment blocks, trailing space in comments 2021-06-24 15:59:34 +10:00