Add a Mesh implementation of triangulation, which is currently just
implemented for BMesh. The main benefit of this is performance and
decreased memory usage. The benefit is especially large because the
node currently converts to BMesh, triangulates, and then converts back.
But the BMesh implementation is entirely single threaded, so it will
always be much slower.
The new implementation uses the principle of "never just process a
single element at a time" but it also tries to avoid processing _too_
many elements at once, to decrease the size of temporary buffers.
Practically that means the work is organized into chunks of selected
faces, but within each chunk, each task is done in a separate loop.
Arguably I went a bit far with some optimizations, and some of the
complexity isn't necessary, but I hope everything is clear anyway.
Unlike some other Mesh ports like the extrude node or the split edges
code, this generates a new mesh. I still go back and forth on that
aspect, but reusing the same mesh would have required reallocating
face attributes from scratch anyway. Implicit sharing is used to
avoid copying vertex attributes though.
The result mesh is reorganized a bit. Unselected face data comes first,
then selected triangles, then triangulated NGons, then triangulated
quads. This makes attribute interpolation and internal calculations
more efficient.
The "Minimum Vertices" socket is replaced with versioning. In the new
implementation it would have an impact on code complexity, and for a
builtin "atomic" node it makes more sense as part of the selection.
The performance difference depends on the number of CPU threads, the
number of attributes, and the selection size. As all of those numbers
go up, the benefit will grow. The "modes" also affect the performance,
obviously.
With a Ryzen 7950x, I tested performance in a few situations (in ms):
| | Selection | Before | After | Change |
| -------------------------- | --------- | ------ | ----- | ------ |
| 1.4 m quads (fixed) | 50% | 1533 | 15.9 | 96x |
| 10 m quads (shortest) | 100% | 9700 | 165.0 | 59x |
| 1 m 10-side Ngons (beauty) | 90% | 3785 | 115.9 | 33x |
| 1 m quads many attributes | 100% | 54600 | 332.3 | 164x |
In follow-up commits, I'll move other areas to use mesh triangulation
instead of BMesh. This is the last geometry node using BMesh besides
the Ico Sphere primitive.
Pull Request: https://projects.blender.org/blender/blender/pulls/112264
We can't use the `threshold` uniform name in Metal because it is used as
a local variable in one of the library files, because uniforms are
defines in Metal, so it causes an error. Change the name to
`color_threshold` as a fix.
The `fmt::format` can process the format string at compile time. Currently, we
don't seem to be using that as we don't use `FMT_STRING`. Starting with C++20,
that will be the default though, and one has to explicitly opt out in places
where the string is not known at compile time using `fmt::runtime(...)`.
Currently, our code does not compile as C++20 because of that. Unfortunately, we
have many places with runtime format strings, because of i18n.
Pull Request: https://projects.blender.org/blender/blender/pulls/130392
There is not really a good definition for what an "attribute kind". There are
many possibilities, it could include domain, type, geometry type, default value,
usage, ...
So it's better not to use this generic name. With the current name, one always
has to look at the definition again to be sure what it contains and what it does
not.
The name `AttributeDomainAndType` is way more explicit and does not have the
same problems. It's a bit longer, but that does not seem to be a problem in the
places where we use it.
Pull Request: https://projects.blender.org/blender/blender/pulls/130505
This probably never in practice in these cases.
Constructing a `std::string` from nullptr is invalid.
Starting with C++23, the `nullptr_t` is even explicitly deleted.
The issue was that pointers to `CustomDataLayer.name` are not stable when
attributes are removed. So the change is to create a temporary copy of the
names that need to be removed.
Pull Request: https://projects.blender.org/blender/blender/pulls/130373
Not sure why I got an error about this today in one of my usual
builds... very mysterious, but the `BLI_array_utils.hh` include does
seem to be missing anyway.
Currently the node behaves differently from the modifier by default
because it lacks the option to use the limit surface. This is mainly
an oversight, since the option gives better results and better
performance.
This adds a new "Limit Surface" option. Because it's on by default,
there is also versioning to turn it off for existing files.
Resolves#112912.
Pull Request: https://projects.blender.org/blender/blender/pulls/130243