Commit Graph

117 Commits

Author SHA1 Message Date
eeb21fc8c3 CustomData: validate layer indices, assert assigned values are valid
Mesh.validate(..) now corrects invalid layer indices.
Add assertion to prevent invalid values being set #105860.
2023-03-23 13:55:51 +11:00
16fbadde36 Mesh: Replace MLoop struct with generic attributes
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
2023-03-20 15:55:13 +01:00
da590428c3 Merge branch 'blender-v3.5-release' 2023-03-17 10:08:42 +01:00
aca3039740 Fix #104730: Suppress using anonymous UV layers for rendering
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: blender/blender#105192
2023-03-17 09:42:54 +01:00
92b607d686 CustomData: add separate function to add layer from existing data
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: blender/blender#105708
2023-03-14 15:30:26 +01:00
e9bb3510a1 Sculpt: Fix #104475, data transfer not respecting vgroup for float colors
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.
2023-02-24 00:00:22 -08:00
ddcf718640 Sculpt: Fix #104475, data transfer not respecting vgroup for float colors
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.
2023-02-22 23:31:44 -08:00
c437a8aea8 Revert release branch only commit after merge
This is a revert of a revert, because the initial revert is only
supposed to be in the release branch.

This reverts commit 3eed00dc54.
2023-02-20 11:51:16 +01:00
3eed00dc54 Revert "GPencil: Include UV information in simplify->sample modifier."
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.
2023-02-20 11:20:07 +01:00
19222627c6 GPencil: Include UV information in simplify->sample modifier.
Simplify modifier sample mode didn't transfer UV parameters, now fixed.

Pull Request #104942
2023-02-19 11:45:22 +01:00
4ec9aff2af Revert "Fix #104850: Create Geometry Nodes operators fails if not in English"
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
2023-02-17 18:45:42 +01:00
68181c2560 Fix #104850: Create Geometry Nodes operators fails if not in English
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
2023-02-17 18:39:17 +01:00
818c16ef1f Cleanup: pass a const argument to CustomData_get_elem_size 2023-02-14 12:26:01 +11:00
dfacaf4f40 Fix: Incorrect BMesh to Mesh attribute copying
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
2023-02-13 20:52:02 +01:00
91346755ce Cleanup: use '#' prefix for issues instead of 'T'
Match the convention from Gitea instead of Phabricator's T for tasks.
2023-02-12 14:56:05 +11:00
88f9c55f7f Sculpt: Fix Dyntopo Warnings
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
2023-02-10 13:16:10 +01:00
266d8de687 Cleanup: spelling in comments 2023-02-03 12:41:01 +11:00
66595e29e2 Cleanup: remove/comment unused code, simplify casts
Remove simple counters where they aren't used, comment in some cases.
Also add missing include.
2023-01-19 17:10:42 +11:00
33c30af742 Cleanup: comments in struct declarations
Use a consistent style for declaring the names of struct members
in their declarations. Note that this convention was already used in
many places but not everywhere.

Remove spaces around the text (matching commented arguments) with
the advantage that the the spell checking utility skips these terms.
Making it possible to extract & validate these comments automatically.

Also use struct names for `bAnimChannelType` & `bConstraintTypeInfo`
which were using brief descriptions.
2023-01-16 13:27:35 +11:00
3a3d9488a1 Refactor: Const correct Custom Data API, prepare for CoW
Currently you can retrieve a mutable array from a const CustomData.
That makes code unsafe since the compiler can't check for correctness
itself. Fix that by introducing a separate function to retrieve mutable
arrays from CustomData. The new functions have the `_for_write`
suffix that make the code's intention clearer.

Because it makes retrieving write access an explicit step, this change
also makes proper copy-on-write possible for attributes.

Notes:
- The previous "duplicate referenced layer" functions are redundant
  with retrieving layers with write access
- The custom data functions that give a specific index only have
  `for_write` to simplify the API

Differential Revision: https://developer.blender.org/D14140
2023-01-13 17:22:07 -06:00
8367f2bffc Cleanup: function style casts for C++ 2023-01-11 13:04:23 +11:00
dd9e1eded0 Mesh: Move sharp edge flag to generic attribute
Move the `ME_SHARP` flag for mesh edges to a generic boolean
attribute. This will help allow changing mesh edges to just a pair
of integers, giving performance improvements. In the future it could
also give benefits for normal calculation, which could more easily
check if all or no edges are marked sharp, which is helpful considering
the plans in T93551.

The attribute is generally only allocated when it's necessary. When
leaving edit mode, it will only be created if an edge is marked sharp.
The data can be edited with geometry nodes just like a regular edge
domain boolean attribute.

The attribute is named `sharp_edge`, aiming to reflect the similar
`select_edge` naming and to allow a future `sharp_face` name in
a separate commit.

Ref T95966

Differential Revision: https://developer.blender.org/D16921
2023-01-10 16:12:14 -05:00
Martijn Versteegh
6c774feba2 Mesh: Move UV layers to generic attributes
Currently the `MLoopUV` struct stores UV coordinates and flags related
to editing UV maps in the UV editor. This patch changes the coordinates
to use the generic 2D vector type, and moves the flags into three
separate boolean attributes. This follows the design in T95965, with
the ultimate intention of simplifying code and improving performance.

Importantly, the change allows exporters and renderers to use UVs
"touched" by geometry nodes, which only creates generic attributes.
It also allows geometry nodes to create "proper" UV maps from scratch,
though only with the Store Named Attribute node for now.

The new design considers any 2D vector attribute on the corner domain
to be a UV map. In the future, they might be distinguished from regular
2D vectors with attribute metadata, which may be helpful because they
are often interpolated differently.

Most of the code changes deal with passing around UV BMesh custom data
offsets and tracking the boolean "sublayers". The boolean layers are
use the following prefixes for attribute names: vert selection: `.vs.`,
edge selection: `.es.`, pinning: `.pn.`. Currently these are short to
avoid using up the maximum length of attribute names. To accommodate
for these 4 extra characters, the name length limit is enlarged to 68
bytes, while the maximum user settable name length is still 64 bytes.

Unfortunately Python/RNA API access to the UV flag data becomes slower.
Accessing the boolean layers directly is be better for performance in
general.

Like the other mesh SoA refactors, backward and forward compatibility
aren't affected, and won't be changed until 4.0. We pay for that by
making mesh reading and writing more expensive with conversions.

Resolves T85962

Differential Revision: https://developer.blender.org/D14365
2023-01-10 01:01:43 -05:00
1af62cb3bf Mesh: Move positions to a generic attribute
**Changes**
As described in T93602, this patch removes all use of the `MVert`
struct, replacing it with a generic named attribute with the name
`"position"`, consistent with other geometry types.

Variable names have been changed from `verts` to `positions`, to align
with the attribute name and the more generic design (positions are not
vertices, they are just an attribute stored on the point domain).

This change is made possible by previous commits that moved all other
data out of `MVert` to runtime data or other generic attributes. What
remains is mostly a simple type change. Though, the type still shows up
859 times, so the patch is quite large.

One compromise is that now `CD_MASK_BAREMESH` now contains
`CD_PROP_FLOAT3`. With the general move towards generic attributes
over custom data types, we are removing use of these type masks anyway.

**Benefits**
The most obvious benefit is reduced memory usage and the benefits
that brings in memory-bound situations. `float3` is only 3 bytes, in
comparison to `MVert` which was 4. When there are millions of vertices
this starts to matter more.

The other benefits come from using a more generic type. Instead of
writing algorithms specifically for `MVert`, code can just use arrays
of vectors. This will allow eliminating many temporary arrays or
wrappers used to extract positions.

Many possible improvements aren't implemented in this patch, though
I did switch simplify or remove the process of creating temporary
position arrays in a few places.

The design clarity that "positions are just another attribute" brings
allows removing explicit copying of vertices in some procedural
operations-- they are just processed like most other attributes.

**Performance**
This touches so many areas that it's hard to benchmark exhaustively,
but I observed some areas as examples.
* The mesh line node with 4 million count was 1.5x (8ms to 12ms) faster.
* The Spring splash screen went from ~4.3 to ~4.5 fps.
* The subdivision surface modifier/node was slightly faster
RNA access through Python may be slightly slower, since now we need
a name lookup instead of just a custom data type lookup for each index.

**Future Improvements**
* Remove uses of "vert_coords" functions:
  * `BKE_mesh_vert_coords_alloc`
  * `BKE_mesh_vert_coords_get`
  * `BKE_mesh_vert_coords_apply{_with_mat4}`
* Remove more hidden copying of positions
* General simplification now possible in many areas
* Convert more code to C++ to use `float3` instead of `float[3]`
  * Currently `reinterpret_cast` is used for those C-API functions

Differential Revision: https://developer.blender.org/D15982
2023-01-10 00:10:43 -05:00
2ffd08e952 Geometry Nodes: deterministic anonymous attribute lifetimes
Previously, the lifetimes of anonymous attributes were determined by
reference counts which were non-deterministic when multiple threads
are used. Now the lifetimes of anonymous attributes are handled
more explicitly and deterministically. This is a prerequisite for any kind
of caching, because caching the output of nodes that do things
non-deterministically and have "invisible inputs" (reference counts)
doesn't really work.

For more details for how deterministic lifetimes are achieved, see D16858.

No functional changes are expected. Small performance changes are expected
as well (within few percent, anything larger regressions should be reported as
bugs).

Differential Revision: https://developer.blender.org/D16858
2023-01-05 14:05:30 +01:00
6514bb05ea Mesh: Store active & default color attributes with strings
Attributes are unifying around a name-based API, and we would like to
be able to move away from CustomData in the future. This patch moves
the identification of active and fallback (render) color attributes
to strings on the mesh from flags on CustomDataLayer. This also
removes some ugliness used to retrieve these attributes and maintain
the active status.

The design is described more here: T98366

The patch keeps forward compatibility working until 4.0 with
the same method as the mesh struct of array refactors (T95965).

The strings are allowed to not correspond to an attribute, to allow
setting the active/default attribute independently of actually filling
its data. When applying a modifier, if the strings don't match an
attribute, they will be removed.

The realize instances / join node and join operator take the names from
the first / active input mesh. While other heuristics may be helpful
(and could be a future improvement), just using the first is simple
and predictable.

Differential Revision: https://developer.blender.org/D15169
2022-12-15 14:21:35 -06:00
a6c822733a BLI: improve CPPType system
* Support bidirectional type lookups. E.g. finding the base type of a
  field was supported, but not the other way around. This also removes
  the todo in `get_vector_type`. To achieve this, types have to be
  registered up-front.
* Separate `CPPType` from other "type traits". For example, previously
  `ValueOrFieldCPPType` adds additional behavior on top of `CPPType`.
  Previously, it was a subclass, now it just contains a reference to the
  `CPPType` it corresponds to. This follows the composition-over-inheritance
  idea. This makes it easier to have self-contained "type traits" without
  having to put everything into `CPPType`.

Differential Revision: https://developer.blender.org/D16479
2022-11-12 18:33:31 +01:00
dc8a1d38b7 Merge branch 'blender-v3.4-release' 2022-11-11 09:09:28 -06:00
ff7645c5ed Fix T102404: Behavior change in CustomData API
Previously the `CustomData_add_layer` function always returned
the existing layer data when used for types that can only have one
layer. This made it work like an "ensure layer exists" function for those
types. That was used in various places to make code more concise.

0a7308a0f1 changed that to always "recreate" the layer even
when it existed. Maybe this is more logical for an "add layer" function,
but that's not clear, and it breaks a bunch of existing code that relied
on the current behavior. Rather than spending a bunch of time going
through uses of the CustomData API, this patch resets the behavior
to what it was before, but adds an assert and a comment to help
avoid memory leaks and other issues. We should focus on moving
to the attribute API instead.

Differential Revision: https://developer.blender.org/D16458
2022-11-11 09:07:54 -06:00
bbb1d3e5e7 Merge branch 'blender-v3.4-release' 2022-11-08 16:28:11 +01:00
0a7308a0f1 Fix: improve CD_ASSIGN handling when adding custom data layer
Previously, the code would incorrectly free the passed in custom data
layer even when `CD_ASSIGN` was not used. Now the function actually
supports assigning the data to the layer. This only fixes the case for
custom data layer types that only support a single layer like `CD_MEDGE`.

Informally reviewed by Hans Goudey.
2022-11-08 16:26:42 +01:00
888fb0b395 Merge branch 'blender-v3.4-release' 2022-11-07 12:32:36 +01:00
e031a45d60 Fix T102238: double free when storing attribute on empty geometry 2022-11-07 11:42:26 +01:00
5060f26f50 Cleanup: Move function to legacy mesh conversion file 2022-11-05 18:14:26 +01:00
a2fcfcabd7 Cleanup: add missing CPPType for MStringProperty 2022-10-18 16:50:42 +02:00
6f190c669f Fix: Attribute layers can be skipped in Mesh to BMesh conversion
In some situations, layers were filled with their default value
when converting from Mesh to BMesh (entering edit mode, for example).
This was caused by the recently added "copy mesh to bmesh" or "merge
mesh to bmesh" custom data functions creating a difference custom
data format than was used for the copying functions used later.

`CustomData_to_bmesh_block` is not robust enough to handle simple
differences in layout between the layout of the source and result
CustomData layers, because it relies on the order of the types and
the number of layers within each type.

As a fix, make the "mesh to bmesh" special case more explicit in
the conversion functions. This makes the difference in the API
smaller, which is a nice improvement anwyay.

Fixes T101796
2022-10-13 12:43:04 -05:00
97746129d5 Cleanup: replace UNUSED macro with commented args in C++ code
This is the conventional way of dealing with unused arguments in C++,
since it works on all compilers.

Regex find and replace: `UNUSED\((\w+)\)` -> `/*$1*/`
2022-10-03 17:38:16 -05:00
8bdd4b4685 Cleanup: use function style casts for C++ 2022-09-30 14:51:49 +10:00
a4ff106c58 Cleanup: Remove more unused CustomData API functions
Due to increased usage of typed arrays in C++ and name/offset based
access for BMesh, these are unlikely to be used again, and haven't been
used in many years.
2022-09-28 23:13:58 -05:00
ff353842bd Cleanup: Deduplicate logic in CustomData access functions
Also remove comments that just restated what the next line
was doing, often incorrectly.
2022-09-28 23:13:58 -05:00
57620af33c Cleanup: Remove unused BMesh function 2022-09-28 23:13:58 -05:00
57ea827bfb Fix: Incorrect handling for crease layers
First, there can only be one crease layer, so remove the "default name",
since apparently that's how CustomData tests for that
(see `CustomData_layertype_is_singleton`).

Second, always propagate crease data because it can be used in arbitrary
situations by geometry nodes. That also has to be done for all generic
attribute layers.

Fixes T101340, T101373
2022-09-26 15:42:29 -05:00
21d77a417e Cleanup: replace C-style casts with functional casts for numeric types
Some changes missed from f68cfd6bb0.
2022-09-25 22:31:31 +10:00
f68cfd6bb0 Cleanup: replace C-style casts with functional casts for numeric types 2022-09-25 20:17:08 +10:00
c7b247a118 Cleanup: replace static_casts with functional casts for numeric types 2022-09-25 18:31:10 +10:00
891949cbb4 Cleanup: use 'u' prefixed integer types for brevity & cast style
To use function style cast '(unsigned char)x' can't be replaced by
'unsigned char(x)'.
2022-09-25 18:26:27 +10:00
12becbf0df Mesh: Move selection flags to generic attributes
Using the attribute name semantics from T97452, this patch moves the
selection status of mesh elements from the `SELECT` of vertices, and
edges, and the `ME_FACE_SEL` of faces to generic boolean attribute
Storing this data as generic attributes can significantly simplify and
improve code, as described in T95965.

The attributes are called `.select_vert`, `.select_edge`, and
`.select_poly`. The `.` prefix means they are "UI attributes",so they
still contain original data edited by users, but they aren't meant to
be accessed procedurally by the user in arbitrary situations. They are
also be hidden in the spreadsheet and the attribute list.

Until 4.0, the attributes are still written to and read from the mesh
in the old way, so neither forward nor backward compatibility are
affected. This means memory requirements will be increased by one byte
per element when selection is used. When the flags are removed
completely, requirements will decrease.

Further notes:
* The `MVert` flag is empty at runtime now, so it can be ignored.
* `BMesh` is unchanged, otherwise the change would be much larger.
* Many tests have slightly different results, since the selection
  attribute uses more generic propagation. Previously you couldn't
  really rely on edit mode selections being propagated procedurally.
  Now it mostly works as expected.

Similar to 2480b55f21
Ref T95965

Differential Revision: https://developer.blender.org/D15795
2022-09-23 10:45:07 -05:00
a8a454287a Mesh: Move edge crease out of MEdge
This is very similar to D14077. There are two differences though.
First is that vertex creases are already stored in a separate layer,
and second is that we can now completely remove use of `Mesh.cd_flag`,
since that information is now inherent to whether the layers exist.

There are two functional differences here:
 * Operators are used to add and remove layers instead of a property.
 * The "crease" attribute can be created and removed by geometry nodes.

The second change should make various geometry nodes slightly faster,
since the "crease" attribute was always processed before. Creases are
now interpolated generically in the CustomData API too, which should
help maintain the values across edits better.

Meshes get an `edge_creases` RNA property like the existing vertex
property, to provide more efficient access to the data in Cycles.

One test failure is expected, where different rounding between float
the old char storage means that 5 additional points are scattered in
a geometry nodes test.

Differential Revision: https://developer.blender.org/D15927
2022-09-23 09:02:28 -05:00
060a534141 Mesh: Move sculpt face sets to a generic attribute
Similar to the other refactors from T95965, this commit moves sculpt
face sets to use a generic integer attribute named `".sculpt_face_set"`.
This makes face sets accessible in the Python API.

The attribute is not visible in the attributes list or the spreadsheet
because it is meant for internal use, though that could be an option
in the future along with other similar attributes. Currently the change
is small, but in the future this could simplify code by allowing use
of more generic attribute APIs.

Differential Revision: https://developer.blender.org/D16045
2022-09-23 08:19:40 -05:00
02575bcbd0 Sculpt: New attribute API
New unified attribute API for sculpt code.

= Basic Design =

The sculpt attribute API can create temporary or permanent attributes (only supported in `PBVH_FACES` mode).  Attributes are created via `BKE_sculpt_attribute_ensure.`

Attributes can be explicit CustomData attributes or simple array-based pseudo-attributes (this is useful for PBVH_GRIDS and PBVH_BMESH).

== `SculptAttributePointers` ==

There is a structure in `SculptSession` for convenience attribute pointers, `ss->attrs`.  Standard attributes should assign these; the attribute API will automatically clear them when the associated attributes are released.  For example, the automasking code stores its factor attribute layer in `ss->attrs.automasking_factor`.

== Naming ==

Temporary attributes should use the SCULPT_ATTRIBUTE_NAME macro for naming, it takes an entry in `SculptAttributePointers` and builds a layer name.

== `SculptAttribute` ==

Attributes are referenced by a special `SculptAttribute` structure, which holds
all the info needed to look up elements of an attribute at run time.

All of these structures live in a preallocated flat array in `SculptSession`, `ss->temp_attributes`.  This is extremely important.  Since any change to the `CustomData` layout can in principle invalidate every extant `SculptAttribute`, having them all in one block of memory whose location doesn't change allows us to update them transparently.

This makes for much simpler code and eliminates bugs.  To see why this is tricky to get right, imagine we want to create three attributes in PBVH_BMESH mode and we provide our own `SculptAttribute` structs for the API to fill in.  Each new layer will invalidate the `CustomData` block offsets in the prior one, leading to memory corruption.

Reviewed by: Brecht Van Lommel
Differential Revision: https://developer.blender.org/D15496
Ref D15496
2022-09-16 12:20:28 -07:00