Part of overall "improve filtering situation" (#116980) task:
* Add Bicubic filtering option to strip Transform "Filter" setting.
Previously this option only existed in Transform Effect "Interpolation"
setting.
- With this addition, it feels like the transform effect could
possibly be marked as legacy/deprecated, since the regular Transform
that is on all strips can do everything that Transform Effect did?
* Speed up bicubic filtering (used now in VSE, but also in CPU Compositor,
image paint, etc.) by slightly simplifying the code and using some SIMD.
Upscaling 96x54 image to 3840x2160 resolution, using Bicubic filtering:
- Windows (VS2022, Ryzen 5950X): 35.5ms -> 15.1ms
- Mac (clang 15, M1 Max): 29.6ms -> 24.4ms
* Add gtest coverage for bicubic functionality.
Pull Request: https://projects.blender.org/blender/blender/pulls/117100
- Move functions to C++ namespace
- Use two functions with simpler responsibilities instead
- Use C++ math functions
- Remove arguments structs left over from before C++ transition
- Return ray distance precalculation by value
Adds a header that defines the same constants as the C++ 20
<numbers> header.
Benefits:
- Decouple our C++ and C math APIs
- Avoid using macros everywhere, nicer syntax
- Less header parsing during compilation
- Can be replaced by `std::numbers` with C++ 20
Downsides:
- There are fewer numbers defined in the C++ standard header
- Maybe we should just wait until we can use C++ 20
Pull Request: https://projects.blender.org/blender/blender/pulls/116805
Converting a near-identity matrix to a euler could be off by over
4.5 degrees when the result of the hypotenuse calculated from the
matrix was small (around 2e-6).
Resolve by increasing the epsilon ~20x to 3.75e-05 which results
in ~1/20th the error.
This was tested against many generated near-identity matrices
(which tend to cause arithmetic error) to ensure this change doesn't
cause worse results in other cases (see report for details).
Bundling many tests in a single binary reduces build time and disk space
usage, but is less convenient for running individual tests command line
as filter flags need to be used.
This adds WITH_TESTS_SINGLE_BINARY to generate one executable file per
source file. Note that enabling this option requires a significant amount
of disk space.
Due to refactoring, the resulting ctest names are a bit different than
before. The number of tests is also a bit different depending if this
option is used, as one uses gtests discovery and the other is organized
purely by filename, which isn't always 1:1.
Co-authored-by: Sergey Sharybin <sergey@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/114604
The delay is caused by `Shortcut->Resolve(0, SLR_NO_UI | SLR_UPDATE)`
to locate potentially moved or renamed paths.
The issue was resolved by adding the `SLR_NOSEARCH` flag.
This eliminates the delay without sacrificing functionality.
Pull Request: https://projects.blender.org/blender/blender/pulls/116692
Along with the 4.1 libraries upgrade, we are bumping the clang-format
version from 8-12 to 17. This affects quite a few files.
If not already the case, you may consider pointing your IDE to the
clang-format binary bundled with the Blender precompiled libraries.
There are some tragic design flaws with the Microsoft STL
implementation of `std::dequeue`. Unless we implement our
own similar data structure or use an implementation from
another library, the change isn't worth it.
This reverts commit b26cd6a4b9.
This reverts commit cc11ba33d9.
This reverts commit c929d75054.
This reverts commit bd3d5a750d.
GSQueue dates back over 21 years, past the initial git commit. Nowadays
we generally prefer to use data structures from the C++ standard library
or our own C++ data structures. Previous commits replaced this container
with `std::queue` in a few areas. Now it is unused and can be removed.
Except for vertex groups and a few older color types, these
are generally replaced by newer generic attribute types.
Also remove some includes of DNA_mesh_types.h, since it's
included indirectly by BKE_mesh.hh currently.
This refactors how volume grids are stored with the following new goals in mind:
* Get a **stand-alone volume grid** data structure that can be used by geometry nodes.
Previously, the `VolumeGrid` data structure was tightly coupled with the `Volume` data block.
* Support **implicit sharing of grids and trees**. Previously, it was possible to share data
when multiple `Volume` data blocks loaded grids from the same `.vdb` files but this was
not flexible enough.
* Get a safe API for **lazy-loading and unloading** of grids without requiring explicit calls
to some "load" function all the time.
* Get a safe API for **caching grids from files** that is not coupled to the `Volume` data block.
* Get a **tiered API** for different levels of `openvdb` involvement:
* No `OpenVDB`: Since `WITH_OPENVDB` is optional, it's helpful to have parts of the API that
still work in this case. This makes it possible to write high level code for volumes that does
not require `#ifdef WITH_OPENVDB` checks everywhere. This is in `BKE_volume_grid_fwd.hh`.
* Shallow `OpenVDB`: Code using this API requires `WITH_OPENVDB` checks. However, care
is taken to not include the expensive parts of `OpenVDB` and to use forward declarations as
much as possible. This is in `BKE_volume_grid.hh` and uses `openvdb_fwd.hh`.
* "Full" `OpenVDB`: This API requires more heavy `OpenVDB` includes. Fortunately, it turned
out to be not necessary for the common API. So this is only used for task specific APIs.
At the core of the new API is the `VolumeGridData` type. It's a wrapper around an
`openvdb::Grid` and adds some features on top like implicit sharing, lazy-loading and unloading.
Then there are `GVolumeGrid` and `VolumeGrid` which are containers for a volume grid.
Semantically, each `VolumeGrid` has its own independent grid, but this is cheap due to implicit
sharing. At highest level we currently have the `Volume` data-block which contains a list of
`VolumeGrid`.
```mermaid
flowchart LR
Volume --> VolumeGrid --> VolumeGridData --> openvdb::Grid
```
The loading of `.vdb` files is abstracted away behind the volume file cache API. This API makes
it easy to load and reuse entire files and individual grids from disk. It also supports caching
simplify levels for grids on disk.
An important new concept are the "tree access tokens". Whenever some code wants to work
with an openvdb tree, it has to retrieve an access token from the corresponding `VolumeGridData`.
This access token has to be kept alive for as long as the code works with the grid data. The same
token is valid for read and write access. The purpose of these access tokens is to make it possible
to detect when some code is currently working with the openvdb tree. This allows freeing it if it's
possible to reload it later on (e.g. from disk). It's possible to free a tree that is referenced by
multiple owners, but only no one is actively working with. In some sense, this is similar to the
existing `ImageUser` concept.
The most important new files to read are `BKE_volume_grid.hh` and `BKE_volume_grid_file_cache.hh`.
Most other changes are updates to existing code to use the new API.
Pull Request: https://projects.blender.org/blender/blender/pulls/116315
When aborting, the Global shared pointer for memory usage tracking
would be freed before Blender's temporary directory was purged.
Removing the temporary directory would then use MEM_* functions which
accessed the freed memory usage class.
Resolve by using malloc/free for the internal recursive_operation(..)
utility function.
Remove strip_last_slash utility function as it's a specific operation
which can be written in 2 lines & was only used once after this change.
This refactors `SocketValueVariant` with the following goals in mind:
* Support type erasure so that not all users of `SocketValueVariant` have
to know about all the types sockets can have.
* Move towards supporting "rainbow sockets" which are sockets whoose
type is only known at run-time.
* Reduce complexity when dealing with socket values in general. Previously,
one had to use `SocketValueVariantCPPType` a lot to manage uninitialized
memory. This is better abstracted away now.
One related change that I had to do that I didn't see coming at first was that
I had to refactor `set_default_remaining_outputs` because now the default value
of a `SocketValueVariant` would not contain any value. Previously, it was
initialized the zero-value of the template parameter. Similarly, I had to change
how implicit conversions are created, because comparing the `CPPType` of linked
sockets was not enough anymore to determine if a conversion is necessary.
We could potentially use `SocketValueVariant` for the remaining socket types in the
future as well. Not entirely sure if that helps yet. `SocketValueVariant` can easily be
adapted to make that work though. That would also justify the name
"SocketValueVariant" better.
Pull Request: https://projects.blender.org/blender/blender/pulls/116231
Add support for enum values in ID properties.
This is needed for the "Menu Switch" node implementation (#113445) which
relies on ID properties for the top-level modifier UI.
Enums items can optionally be added to the UI data of integer
properties. Each property stores a full set of the enum items to keep
things simple.
Enum items can be added to properties using the `id_properties_ui`
function in the python API. A detailed example can be found in the
`bl_pyapi_idprop.py` test.
There is currently no support yet for editing enum items through the UI.
This is because the "Edit Property" feature is implemented entirely
through a single operator (`WM_OT_properties_edit`) and its properties.
Buttons to add/remove/move items would be operators changing another
operator's properties. A refactor of the custom properties UI is likely
required to make this work.
Pull Request: https://projects.blender.org/blender/blender/pulls/114362
The only user was the Python API. Convert that to use the C++ API.
That simplifies things a bit even, since the encoding of "arrays of arrays"
is a fair amount simpler with the C++ data structures. The motivation
is to simplify the changes from #111061.
IMB_transform is used by Sequencer (and other places) to do image
translation/rotation/scale on the CPU. This PR speeds up parts of it,
particularly when bilinear filtering is used. No behavior changes are
expected.
- Don't use virtual function calls inside inner loop. The code was using
class hierarchies with virtual calls just to do equivalent of "outside
of image? ignore" and "wrap UV coordinates or not?" decisions. Make those
use non-virtual function based code.
- Simplify pixel sampling functions to only do the work as needed by
anything within Blender codebase. For example, bilinear sampling of uchar
images always uses 4 RGBA channels and never does "UV wrap" logic.
- Bilinear interpolation uchar: completely branchless SIMD code now.
- Bilinear interpolation float: 2x floor() calls instead of 4x floor() +
2x ceil(), and final sample blending is done with SIMD.
Sequencer at 4K UHD resolution, with two image strips that need a transform,
playback framerate:
- Windows Ryzen 5950X: 18.7fps -> 26.2fps (IMB_transform time per frame goes
26.3ms -> 11.2ms)
- Mac M1 Max: 27.3fps -> 31.4fps
At that point the IMB_transform is not the slowest part of where playback
takes time (but rather sequencer effect application etc.).
Note: the amount of _actual code_ got a bit smaller. But I've added 100 lines
of unit tests in BLI_math_interp_test.cc, the bilinear interpolation
functions were only tested very indirectly by CPU compositor template
image tests.
Pull Request: https://projects.blender.org/blender/blender/pulls/115653
`Vector::remove_if` allows certain elements to be removed based on a predicate.
However `std::remove_if` only shifts the elements that will not be deleted
to the beginning of the container and then `Vector::remove_if` only
updates the pointer to the new last element after using `std::remove_if`.
This works well if `Vector` is used with trivial types that don't have a destructor.
Having a `Vector<std::unique_ptr>` for example, can generate undefined behavior
if the predicate gives `true` to elements that are contiguous at the end, if
`Vector::remove_if` only updates the end pointer in these specific cases, these
makes these smart pointers useless because they will not be freed by themselves.
To prevent that, also destruct the elements being removed.
Pull Request: https://projects.blender.org/blender/blender/pulls/115914
The logic can be much simpler when curves are selected rather than points,
because then we just copy all of the points in each curve. Like some other
operators, implement both cases.