`CD_HAIRLENGTH` is not really a custom data type, it was just used to
specify the hair particle "length" attribute to pass it to EEVEE and
material preview. Because of the "typemap" array in `CustomData`,
it's better not to have this unnecessary type. Instead, use the same
mechanism used to request the active color attribute.
Pull Request: https://projects.blender.org/blender/blender/pulls/109449
Store subdivision surface creases in two new named float attributes:
- `crease_vert`
- `crease_edge`
This is similar to 2a56403cb0.
The attributes are naming conventions, so their data type and domain
aren't enforced, and may be interpolated when necessary. Editing tools
and the subdivision surface modifier use the hard-coded name. It might
be best if these were edited as generic attributes in the future, but
in the meantime using generic attributes helps.
The attributes are visible in the list, which is how they're now meant
to be removed. They are now interchangeable with any tool that works
with the generic attribute system-- even tools like vertex paint can
affect creases now.
This is a breaking change. Forward compatibility isn't preserved for
versions before 3.6, and the `crease` property in RNA is removed in
favor of making a smaller API surface area with just the attribute API.
`Mesh.vertex_creases` and `Mesh.edge_creases` now just return the
matching attribute if possible, and are now implemented in Python.
New functions `*ensure` and `*remove` also replace the operators to
add and remove the layers for Python.
A few extrude node test files have to be updated because of different
(now generic) attribute interpolation behavior.
Pull Request: https://projects.blender.org/blender/blender/pulls/108089
Add a quaternion attribute type that will be used in combination with
rotation sockets for geometry nodes to give a more intuitive experience
and better performance when using rotations.
The most interesting part is probably the interpolation, the rest is
the same as the last attribute type addition, 988f23cec3.
We need to interpolate multiple values with different weights.
Based on Sybren's suggestion, this uses the `expmap` methods from
4805a54525 for that.
This also refactors `SimpleMixerWithAccumulationType` to use a
function rather than a cast to convert to the accumulation type.
See #92967
Pull Request: https://projects.blender.org/blender/blender/pulls/108678
The data transfer code stored values not in the `eCustomDataType`
enum in this variable, so the type was incorrect. Instead use a cast
when we expect the value to be a valid enum value.
Face maps were added as a prototype of a new rigging solution during
2.8 development. Their storage is redundant with the newer generic
attribute system (specifically with integer face attributes), and
they were never used much. This commit removes the face map list
and converts the storage to an attribute with the name `face_maps`.
There is nowhere to store the face map names anymore, so those
are not kept.
It probably still makes sense to have a feature like mesh face gizmo
selection for rigging. But the design and implementation woulds likely
have to change significantly, including possibly changing the storage
type, and making use of the generic attribute system instead of a
special type.
See #105317 for more discussion.
A lot of files were missing copyright field in the header and
the Blender Foundation contributed to them in a sense of bug
fixing and general maintenance.
This change makes it explicit that those files are at least
partially copyrighted by the Blender Foundation.
Note that this does not make it so the Blender Foundation is
the only holder of the copyright in those files, and developers
who do not have a signed contract with the foundation still
hold the copyright as well.
Another aspect of this change is using SPDX format for the
header. We already used it for the license specification,
and now we state it for the copyright as well, following the
FAQ:
https://reuse.software/faq/
Covers the macro ARRAY_SIZE() and STRNCPY.
The problem this change is aimed to solve it to provide cross-platform
compiler-independent safe way pf ensuring that the functions are used
correctly.
The type safety was only ensured for GCC and only for C. The C++
language and Clang compiler would not have detected issues of passing
bare pointer to neither of those macros.
Now the STRNCPY() will only accept a bounded array as the destination
argument, on any compiler.
The ARRAY_SIZE as well, but there are a bit more complications to it
in terms of transparency of the change.
In one place the ARRAY_SIZE was used on float3 type. This worked in the
old code because the type implements subscript operator, and the type
consists of 3 floats. One would argue this is somewhat hidden/implicit
behavior, which better be avoided. So an in-lined value of 3 is used now
there.
Another place is the ARRAY_SIZE used to define a bounded array of the
size which matches bounded array which is a member of a struct. While
the ARRAY_SIZE provides proper size in this case, the compiler does not
believe that the value is known at compile time and errors out with a
message that construction of variable-size arrays is not supported.
Solved by converting the field to std::array<> and adding dedicated
utility to get size of std::array at compile time. There might be a
better way of achieving the same result, or maybe the approach is
fine and just need to find a better place for such utility.
Surely, more macro from the BLI_string.h can be covered with the C++
inlined functions, but need to start somewhere.
There are also quite some changes to ensure the C linkage is not
enforced by code which includes the headers.
Pull Request: https://projects.blender.org/blender/blender/pulls/108041
Store bevel weights in two new named float attributes:
- `bevel_weight_vert`
- `bevel_weight_edge`
These attributes are naming conventions. Blender doesn't enforce
their data type or domain at all, but some editing features and
modifiers use the hard-coded name. Eventually those tools should
become more generic, but this is a simple change to allow more
flexibility in the meantime.
The largest user-visible changes are that the attributes populate the
attribute list, and are propagated by geometry nodes. The method of
removing this data is now the attribute list as well.
This is a breaking change. Forward compatibility is not preserved, and
the vertex and edge `bevel_weight` properties are removed. Python API
users are expected to use the attribute API to get and set the values.
Fixes#106949
Pull Request: https://projects.blender.org/blender/blender/pulls/108023
A NULL defname would early exit (doing nothing) this isn't good behavior
as this function should always make the name unique and a NULL defname
is likely an error in the code which would allow duplicate names.
This is also inconsistent with BLI_uniquename_cb which always
wrote the defname into the name if it was empty.
Mark this argument as never-NULL.
The main goal of these changes is to support checking if some data has
been changed over time. This is used by the WIP simulation nodes during
baking to detect which attributes have to be stored in every frame because
they have changed.
By using a combination of a weak user count and a version counter, it is
possible to detect that an attribute (or any data controlled by implicit
sharing) has not been changed with O(1) memory and time. It's still
possible that the data has been changed multiple times and is the same
in the end and beginning of course. That wouldn't be detected using this
mechanism.
The `ImplicitSharingInfo` struct has a new weak user count. A weak
reference is one that does not keep the referenced data alive, but makes sure
that the `ImplicitSharingInfo` itself is not deleted. If some piece of
data has one strong and multiple weak users, it is still mutable. If the
strong user count goes down to zero, the referenced data is freed.
Remaining weak users can check for this condition using `is_expired`.
This is a bit similar to `std::weak_ptr` but there is an important difference:
a weak user can not become a strong user while one can create a `shared_ptr`
from a `weak_ptr`. This restriction is necessary, because some code might
be changing the referenced data assuming that it is the only owner. If
another thread suddenly adds a new owner, the data would be shared again
and the first thread would not have been allowed to modify the data in
the first place.
There is also a new integer version counter in `ImplicitSharingInfo`.
It is incremented whenever some code wants to modify the referenced data.
Obviously, this can only be done when the data is not shared because then
it would be immutable. By comparing an old and new version number of the
same sharing info, one can check if the data has been modified. One has
to keep a weak reference to the sharing info together with the old version
number to ensure that the new sharing info is still the same as the old one.
Without this, it can happen that the sharing info was freed and a new
one was allocated at the same pointer address. Using a strong reference
for this purpose does not work, because then the data would never be
modified because it's shared.
Generally, one does not know if the sharing info is currently shared
and should therefore be const. Better keep it const almost all the
time and only remove the constness when absolutely necessary
and the code has checked that it is valid.
Implements #95966, as the final step of #95965.
This commit changes the storage of mesh edge vertex indices from the
`MEdge` type to the generic `int2` attribute type. This follows the
general design for geometry and the attribute system, where the data
storage type and the usage semantics are separated.
The main benefit of the change is reduced memory usage-- the
requirements of storing mesh edges is reduced by 1/3. For example,
this saves 8MB on a 1 million vertex grid. This also gives performance
benefits to any memory-bound mesh processing algorithm that uses edges.
Another benefit is that all of the edge's vertex indices are
contiguous. In a few cases, it's helpful to process all of them as
`Span<int>` rather than `Span<int2>`. Similarly, the type is more
likely to match a generic format used by a library, or code that
shouldn't know about specific Blender `Mesh` types.
Various Notes:
- The `.edge_verts` name is used to reflect a mapping between domains,
similar to `.corner_verts`, etc. The period means that it the data
shouldn't change arbitrarily by the user or procedural operations.
- `edge[0]` is now used instead of `edge.v1`
- Signed integers are used instead of unsigned to reduce the mixing
of signed-ness, which can be error prone.
- All of the previously used core mesh data types (`MVert`, `MEdge`,
`MLoop`, `MPoly` are now deprecated. Only generic types are used).
- The `vec2i` DNA type is used in the few C files where necessary.
Pull Request: https://projects.blender.org/blender/blender/pulls/106638
This type will be used to store mesh edges in #106638, but it could
be used for anything else too. This commit adds support for:
- The new type in the Python API
- Editing the type in the edit mode "Attribute Set" operator
- Rendering the type in EEVEE and Cycles for all geometry types
- Geometry nodes attribute interpolation and mixing
- Viewing the type in the spreadsheet and using row filters
The attribute uses the `blender::int2` type in most code, and
the `vec2i` DNA type in C code when necessary. The enum names
are based on `INT32_2D` for consistency with `INT8` and `INT32`.
Pull Request: https://projects.blender.org/blender/blender/pulls/106677
This integrates the new implicit-sharing system (from fbcddfcd68)
with `CustomData`. Now the potentially long arrays referenced by custom
data layers can be shared between different systems but most importantly
between different geometries. This makes e.g. copying a mesh much cheaper
because none of the attributes has to be copied. Only when an attribute
is modified does it have to be copied.
Also see the original design task: #95845.
This reduces memory and improves performance by avoiding unnecessary
data copies. For example, the used memory after loading a highly
subdivided mesh is reduced from 2.4GB to 1.79GB. This is about 25%
less which is the expected amount because in `main` there are 4 copies
of the data:
1. The original data which is allocated when the file is loaded.
2. The copy for the depsgraph allocated during depsgraph evaluation.
3. The copy for the undo system allocated when the first undo step is
created right after loading the file.
4. GPU buffers allocated for drawing.
This patch only gets rid of copy number 2 for the depsgraph. In theory
the other copies can be removed as part of follow up PRs as well though.
-----
The patch has three main components:
* Slightly modified `CustomData` API to make it work better with implicit
sharing:
* `CD_REFERENCE` and `CD_DUPLICATE` have been removed because they are
meaningless when implicit-sharing is used.
* `CD_ASSIGN` has been removed as well because it's not an allocation
type anyway. The functionality of using existing arrays as custom
data layers has not been removed though.
* This can still be done with `CustomData_add_layer_with_data` which
also has a new argument that allows passing in information about
whether the array is shared.
* `CD_FLAG_NOFREE` has been removed because it's no longer necessary. It
only existed because of `CD_REFERENCE`.
* `CustomData_copy` and `CustomData_merge` have been split up into a
functions that do copy the actual attribute values and those that do
not. The latter functions now have the `_layout` suffix
(e.g. `CustomData_copy_layout`).
* Changes in `customdata.cc` to make it actually use implicit-sharing.
* Changes in various other files to adapt to the changes in `BKE_customdata.h`.
Pull Request: https://projects.blender.org/blender/blender/pulls/106228
There is no point in checking if the allocation of this relatively
small array was successful. We only do that in very few places,
but here it just adds unnecessary complexity.
Autosave files are created from memfile undo, which
doesn't save legacy mesh data. This leads to a crash
on file load.
In addition the mesh code can now add CustomData
layers when saving files, which did not work if
the original domain had no layers. In that case
CustomData.layers is NULL and DNA has nothing to
key off of when loading the file later.
Pull Request: https://projects.blender.org/blender/blender/pulls/106648
Implements #95967.
Currently the `MPoly` struct is 12 bytes, and stores the index of a
face's first corner and the number of corners/verts/edges. Polygons
and corners are always created in order by Blender, meaning each
face's corners will be after the previous face's corners. We can take
advantage of this fact and eliminate the redundancy in mesh face
storage by only storing a single integer corner offset for each face.
The size of the face is then encoded by the offset of the next face.
The size of a single integer is 4 bytes, so this reduces memory
usage by 3 times.
The same method is used for `CurvesGeometry`, so Blender already has
an abstraction to simplify using these offsets called `OffsetIndices`.
This class is used to easily retrieve a range of corner indices for
each face. This also gives the opportunity for sharing some logic with
curves.
Another benefit of the change is that the offsets and sizes stored in
`MPoly` can no longer disagree with each other. Storing faces in the
order of their corners can simplify some code too.
Face/polygon variables now use the `IndexRange` type, which comes with
quite a few utilities that can simplify code.
Some:
- The offset integer array has to be one longer than the face count to
avoid a branch for every face, which means the data is no longer part
of the mesh's `CustomData`.
- We lose the ability to "reference" an original mesh's offset array
until more reusable CoW from #104478 is committed. That will be added
in a separate commit.
- Since they aren't part of `CustomData`, poly offsets often have to be
copied manually.
- To simplify using `OffsetIndices` in many places, some functions and
structs in headers were moved to only compile in C++.
- All meshes created by Blender use the same order for faces and face
corners, but just in case, meshes with mismatched order are fixed by
versioning code.
- `MeshPolygon.totloop` is no longer editable in RNA. This API break is
necessary here unfortunately. It should be worth it in 3.6, since
that's the best way to allow loading meshes from 4.0, which is
important for an LTS version.
Pull Request: https://projects.blender.org/blender/blender/pulls/105938
The goal is to solve confusion of the "All rights reserved" for licensing
code under an open-source license.
The phrase "All rights reserved" comes from a historical convention that
required this phrase for the copyright protection to apply. This convention
is no longer relevant.
However, even though the phrase has no meaning in establishing the copyright
it has not lost meaning in terms of licensing.
This change makes it so code under the Blender Foundation copyright does
not use "all rights reserved". This is also how the GPL license itself
states how to apply it to the source code:
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software ...
This change does not change copyright notice in cases when the copyright
is dual (BF and an author), or just an author of the code. It also does
mot change copyright which is inherited from NaN Holding BV as it needs
some further investigation about what is the proper way to handle it.
The overall goal is to use implicit-sharing in many places in Blender
that currently do unnecessary copies. See #95845 for more details.
This commit only adds the base data structures in blenlib and uses those
in `GeometrySet` and `AnonymousAttributeID`, which used a more ad-hoc
version of implicit sharing already. #105994 lists some more places where
support for implicit sharing can be added (most notably: custom data layers).
Pull Request: https://projects.blender.org/blender/blender/pulls/105994
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: https://projects.blender.org/blender/blender/pulls/104424
When an object has no UV layers and an anonymous UV layer is created,
the anonymous layer gets set as the default (render) layer. This is
very confusing because it then uses a hidden anonmous layer. This patch
suppresses the usage of anonymous layers for rendering.
Pull Request: https://projects.blender.org/blender/blender/pulls/105192
This simplifies the usage of the API and is preparation for #104478.
The `CustomData_add_layer` and `CustomData_add_layer_named` now have corresponding
`*_with_data` functions that should be used when creating the layer from existing data.
Pull Request: https://projects.blender.org/blender/blender/pulls/105708
This might've been a merge error, the result of color mixing
was being overwritten by a simple copy of source to destination
inside of layerCopyValue_propcol.
This might've been a merge error, the result of color mixing
was being overwritten by a simple copy of source to destination
inside of layerCopyValue_propcol.
This reverts commit 19222627c6.
Something went wrong here, seems like this commit merged the main branch
into the release branch, which should never be done.
This reverts commit 68181c2560.
I merged 3.6 into 3.5 by mistake. Basically I had a PR against main,
then changed it in the last minute to be against 3.5 via the
web-interface unaware that I shouldn't do it without updating the
patch.
Original Pull Request: #104889
Note that the node group has its sockets names
translated, while the built-in nodes don't.
So we need to use data_ for the built-in nodes names,
and the sockets of the created node groups.
Pull Request #104889
The existing logic to copy `BMesh` custom data layers to `Mesh`
attribute arrays was quite complicated, and incorrect in some cases
when the source and destinations didn't have the same layers.
The functions leave a lot to be desired in general, since they have
a lot of redundant complexity that ends up doing the same thing for
every element.
The problem in #104154 was that the "rest_position" attribute overwrote
the mesh positions since it has the same type and the positions weren't
copied. This same problem has shown up in boolean attribute conversion
in the past. Other changes fixed some specific cases but I think a
larger change is the only proper solution.
This patch adds preprocessing before looping over all elements to
find the basic information for copying the relevant layers, taking
layer names into account. The preprocessing makes the hot loops
simpler.
In a simple file with a 1 million vertex grid, I observed a 6%
improvement animation playback framerate in edit mode with a simple
geometry nodes modifier, from 5 to 5.3 FPS.
Fixes#104154, #104348
Pull Request #104421
Because of T95965, some attributes are stored as generic attributes
in Mesh but have special handling for the conversion to BMesh.
Expose a function to tell whether certain attribute names are handled
specially in the conversion, and refactor the error checking process
to use it. Also check for generic attributes on the face domain which
wasn't done before.
Author: Hans Goudey
Reviewed By: Joseph Eagar
Co-authored-by: Joseph Eagar <joeedh@gmail.com>
Pull Request #104567