Implements #102359.
Split the `MLoop` struct into two separate integer arrays called
`corner_verts` and `corner_edges`, referring to the vertex each corner
is attached to and the next edge around the face at each corner. These
arrays can be sliced to give access to the edges or vertices in a face.
Then they are often referred to as "poly_verts" or "poly_edges".
The main benefits are halving the necessary memory bandwidth when only
one array is used and simplifications from using regular integer indices
instead of a special-purpose struct.
The commit also starts a renaming from "loop" to "corner" in mesh code.
Like the other mesh struct of array refactors, forward compatibility is
kept by writing files with the older format. This will be done until 4.0
to ease the transition process.
Looking at a small portion of the patch should give a good impression
for the rest of the changes. I tried to make the changes as small as
possible so it's easy to tell the correctness from the diff. Though I
found Blender developers have been very inventive over the last decade
when finding different ways to loop over the corners in a face.
For performance, nearly every piece of code that deals with `Mesh` is
slightly impacted. Any algorithm that is memory bottle-necked should
see an improvement. For example, here is a comparison of interpolating
a vertex float attribute to face corners (Ryzen 3700x):
**Before** (Average: 3.7 ms, Min: 3.4 ms)
```
threading::parallel_for(loops.index_range(), 4096, [&](IndexRange range) {
for (const int64_t i : range) {
dst[i] = src[loops[i].v];
}
});
```
**After** (Average: 2.9 ms, Min: 2.6 ms)
```
array_utils::gather(src, corner_verts, dst);
```
That's an improvement of 28% to the average timings, and it's also a
simplification, since an index-based routine can be used instead.
For more examples using the new arrays, see the design task.
Pull Request: blender/blender#104424
133dde41bb changed how 'fake user' flag is handled with linked data.
Previous behavior was a bug/inconsistency, in that the 'directly linked'
tag would be 'over-set' and never cleared, forcing saving references to
a lot of unused linked data.
Note that ideally, 'Fake user' flag should be ignored, and the only way
to decide whether to keep or not a linked ID should be whether it's
actually used by some local data.
However, #103867 and #105687 show that this is causing issues in some cases,
where users wrongly relied on the linked data's pre-defined 'Fake user' flag
to keep their linked data in their production files, even if said data had no
real user.
While not ideal, for now we should consider 'fake user' flag for linked data
as a real usage case. A better handling of this edge-case is related to
wider designs aboud handling of 'non used' data on file save, whether
linked IDs should keep track of being explicitly or implicitly linked by
the user, etc.
Align the labels on the tabs so that when you read them, your head is tilted
towards the content, instead of away.
When tabs are drawn to the right of panels in the sidebar, the labels are read
from bottom to top, which may suggest that this tab does not belong to the area.
This change does it like this:
* Sidebar on the right: the text is read from top to bottom.
* Sidebar on the left: the text keeps reading from bottom to top.
Pull Request: blender/blender#105835
The NLA's behaviour of always forcing a full set of keys (XYZW) is now
done in both 'Combine' and 'Replace' mode (previously only the former).
This fixes the bug where quaternions could not be properly keyed in 'full
stack tweak mode' under certain conditions.
Pull Request: blender/blender#105604
The name #ensure_valid_reflection seems to indicate that the resulted
reflection must be valid, whereas in the reality it only ensure validity
for specular reflections. The new name matches the behavior better.
Actually both potential roots lie in the interval [0, 1], so the
function ended up checking both roots all the time.
The new implementation explains why only one of the roots is valid; it
saves two square roots and a bunch of other computations.
The `NODE_OT_link_viewer` operator has some complicated logic that was
intended to stop cycling through geometry nodes to make it work better
with nodes that have multiple geometry and data outputs (group nodes).
This logic failed when geometry was not the first socket and it would
just stop connecting data sockets altogether after the geometry socket.
The reason is that the `determine_socket_to_view` function stops looking
for already-viewed outputs after the first geometry, and then simply
reconnects that geometry.
This patch changes the behavior slightly so that, if a geometry output
is found, the node skips over all subsequent geometry outputs, but still
considers data sockets for viewing. Viewing a node with multiple geometry
outputs will connect the first geometry output it encounters and then
keep cycling through data outputs on repeated execution.
Pull Request: #105836
The Cycles light linking branch is using the tree view UI but it seemed
to use the "wrong" layout. It wasn't clear that the layout has to be
reactivated before building the view.
Make it harder to use the API wrong now by requiring the layout as
argument, so the building can ensure it's active.
The input file contains a partial cube, with two regular faces, two
loose edges and one loose vertex. This checks whether the loose vertex
for example is included into the output when exporting with UVs
(loose verts do not have UVs in Blender, so they should get (0,0) UV
in PLY).
In a previous step of the mesh writing process, the loop `totlayer` was
replaced and a temporary vector is used for layer data instead. Use this
temporary vector to find the UV sub-layers, since the vector and the
CustomData struct in the mesh don't necessarily match. Also use a
local variable for mesh loop count to make it clearer that the mesh
isn't used except at the end.
Thanks to Campbell for finding the source of this error.
Since UVs are now stored as 2D vectors in meshes, they can be copied
directly to the vertex buffers. Somewhat surprisingly, multithreading
the copying into the vertex buffer provides a good speedup-- on a CPU
with many cores at least.
Here is a test uploading two UV maps created in geometry
nodes with a 1 million quad mesh, with a Ryzen 7950x:
| | Before | After | Speedup |
| ------- | ------- | ------ | ------- |
| Average | 24.3 ms | 7.5 ms | 3.2x |
| Min | 17.6 ms | 7.0 ms | 2.5x |
I added the copying utilities to the array utils header, since the
need for them has come up in a few different places already, and the
existing function with a selection argument didn't make sense here.
Pull Request: blender/blender#105793
When deleting UV UI attributes it isn't necessary to use the higher
level C attribute API, since we already know we aren't working with
the edit mesh here.
There were logic errors and use-after-free errors with the attribute
removal function. Because the custom data layers are reallocated,
we can't reuse the name pointer after removing an attribute. And
we can't return early on the first domain to fail for the edit mode
implementation, because another domain might have the attribute.
Also reorganize some of the code to make the logic clearer: only remove
sub-attribuutes and change attribute names after actually removing the
attribute,and assert if the attribute isn't removed after it is found.
Geometry Nodes: SDF Volume nodes milestone 1
Adds initial support for SDF volume creation and manipulation.
`SDF volume` is Blender's name of an OpenVDB grid of type Level Set.
See the discussion about naming in #91668.
The new nodes are:
- Mesh to SDF Volume: Converts a mesh to an SDF Volume
- Points to SDF Volume: Converts points to an SDF Volume
- Mean Filter SDF Volume: Applies a Mean Filter to an SDF
- Offset SDF Volume: Applies an offset to an SDF
- SDF Volume Sphere: Creates an SDF Volume in the shape of a sphere
For now an experimental option `New Volume Nodes` needs to be
enabled in Blender preferences for the nodes to be visible.
See the current work plan for Volume Nodes in #103248.
Pull Request: blender/blender#105090
The crash is fixed by reverting 87fd798ae3 and
some follow up commits. While it would generally be nice to move to a more
SoA format for these things, we are not there yet and this is causing more
trouble than it's worth currently. The main difficulty is that the socket
indices are changed by many different operations which invalidates the array
too often and led to many follow up bugs.
Pull Request: blender/blender#105877
Change code fragments where `BKE_mesh_vert_coords_alloc` had been used
to temporarily copy vertex coordinates of a mesh (see #103789) and
providd pointers to the mesh's stored vertex positions instead.
This reduces memory usage and improves performance.
Pull Request: blender/blender#105756
Implement GBuffer prepass and deferred lighting (lights only).
This decouple lighting from the material shaders making them lighter,
less expensive and faster to compile.
Trying to keep a nice data flow so we could potentially use the
subpass programable blending feature on tiled GPU arch.
Not everything is covered yet and #105880 is making the GBuffer layout
a bit awkward and not easily extendable.
Pull Request: blender/blender#105868
Changed `edge->v2` to `endVert` to make it consistent with surrounding code.
Removed the unused `totedges` variable.
Currently `totpoly` is also unused, but is fixed in a separate PR.
Pull Request: blender/blender#105870
Follow connections when reading the varname attribute of a primvar
reader, and support both string and TfToken types for the varname.
A unit test is also provided.
Authored by Apple: Matt McLin
Pull Request: blender/blender#105508
This was lost in the refactor to store material indices in a generic attribute.
The attribute API still allows this, but that will be handled separately
since it's a more complex task. The existing API that already clamped
input values should still do that.
Other areas like blenkernel and Cycles clamp the material indices to be
positive so this should be consistent with them. There is still discussion
if material indices should be made impossible, but this at least avoids
crashing for the 3.5 release.
There was also an inconsistency in how sculpt mode handles material index
higher than the number of slots.
Ref #105577
This flag is moved to a different variable but the default value is still placed on the wrong variable.
This fixes the default value assignment but due to the old flag bits are in conflict with used bits in the new flag variables, versioning changes are not included.
Pull Request: blender/blender#105852
1) There was a logic error in FileBuffer where when it was trying to
add a new 64kb chunk to hold output, it was adding an empty chunk,
but making sure we have space capacity to hold 64 thousand chunks.
So that was a bit of pointless juggling to get nothing good.
2) In UV_vertex_key, instead of trying to combine three members into
a hash value, badly, by doing some ad-hoc shifts and xors, use
get_default_hash_3 instead, which combines them way more properly.
Also avoid copying the whole hash map object.
On my windows box (Ryzen 5950X, VS2022), exporting Stanford Lucy 3D
scan:
- Binary: 13.4 -> 5.4 sec
- ASCII: 29.3 -> 14.6 sec
So basically 2x faster for two tiny changes.