Commit Graph

3026 Commits

Author SHA1 Message Date
Hans Goudey
d7ac2a177a Cleanup: Use spans and C++ type to access mesh normals
Also rename some variables to use names consistent with elsewhere.
2023-03-15 14:03:05 -04:00
Hans Goudey
ee18b625ca Fix: Edit mesh face corner color operators always use first layer
The operator went through quite a bit of trouble to pass a color
attribute index to the operator, but then it always used the offset
from the first layer of the active color attribute's type.

Also remove the "copy domains temp" API function, which
generalized this more than necessary, and exposed the internals
of the custom data system a bit more than we would like.
2023-03-14 12:03:46 -04:00
Jacques Lucke
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: https://projects.blender.org/blender/blender/pulls/105708
2023-03-14 15:30:26 +01:00
Campbell Barton
19565469c8 Merge branch 'blender-v3.5-release' 2023-03-14 13:41:43 +11:00
Campbell Barton
1c88bf6ce1 Fix #105715: Freeing the edit-mesh causes future access to fail
The BPyBMesh in `BMesh::py_handle` was invalidated but not cleared,
causing future access to return a 'dead' bmesh.
2023-03-14 13:36:54 +11:00
Hans Goudey
46da66f4df Fix: Uninitialized boolean arrays in mesh conversion
In practice this probably didn't cause bugs, but it would have
caused extra copies of the UV helper layers. The layers are only
needed if we find true values. Mistake in 0fe0db63d7.
2023-03-13 17:32:20 -04:00
Hans Goudey
2ae9526cd9 Cleanup: Small changes in Mesh BMesh conversion
Tweak variable naming, remove a few unnecessary comments,
remove a timer accidentally committed previously.
2023-03-13 09:20:15 -04:00
Hans Goudey
0fe0db63d7 Mesh: Optimize BMesh to Mesh conversion with UV maps
The BMesh to Mesh conversion does some checks to the UV helper
attributes like selection to avoid copying them to the mesh if they
don't contain any meaningful data. However, it does this by looping
over all faces for every UV map, not in parallel, so it takes up a large
portion of the total time in the conversion. This commit moves that
to the existing similar checks.

On a 1 million face mesh with 3 UV maps, for me this improved the
conversion runtime by 75%, from 174ms to 99ms. Before the serial
loops took 88ms out of the total. Combining them with the existing
loop over faces only increased its runtime from 29 to 40ms.
2023-03-13 09:07:52 -04:00
Hans Goudey
1dc57a89e9 Mesh: Move functions to C++ header
Refactoring mesh code, it has become clear that local cleanups and
simplifications are limited by the need to keep a C public API for
mesh functions. This change makes code more obvious and makes further
refactoring much easier.

- Add a new `BKE_mesh.hh` header for a C++ only mesh API
- Introduce a new `blender::bke::mesh` namespace, documented here:
  https://wiki.blender.org/wiki/Source/Objects/Mesh#Namespaces
- Move some functions to the new namespace, cleaning up their arguments
- Move code to `Array` and `float3` where necessary to use the new API
- Define existing inline mesh data access functions to the new header
- Keep some C API functions where necessary because of RNA
- Move all C++ files to use the new header, which includes the old one

In the future it may make sense to split up `BKE_mesh.hh` more, but for
now keeping the same name as the existing header keeps things simple.

Pull Request: https://projects.blender.org/blender/blender/pulls/105416
2023-03-12 22:29:15 +01:00
Hans Goudey
5669c5a61b Mesh: Parallelize BMesh to Mesh conversion
This is very similar to ebe8f8ce71, but applies the same
changes to conversions to non-evaluated meshes meant for original
data. The function also handles shape keys, UVs, selection history,
"scan the database" object vertex index remapping, and multires fixes.
Those operations are handled in parallel with the other conversions now.

Similar to before, the improvement is better the more attributes/data
contained in the BMesh. This time I observed an improvement of 50%
(182ms to 123ms) for a large grid mesh with many attributes, and 20%
for a large grid mesh with less data. Shape keys, selection, hiding, and
multires data should have less of a detriment to performance now too.

One remaining thing to improve is the recently added UV selection/pin
handling. This should be moved into the first single-threaded loop over
faces, or changed further.

Pull Request: https://projects.blender.org/blender/blender/pulls/105602
2023-03-12 21:50:14 +01:00
Hans Goudey
85fb63f99c Cleanup: Move functions in BMesh Mesh conversion
These functions will be useful to speed up the edit mode to object
mode conversion too, move them above that so they can easily be
used for that case later.
2023-03-09 09:41:26 -05:00
Campbell Barton
b3625e6bfd Cleanup: comment blocks 2023-03-09 10:39:49 +11:00
Hans Goudey
5876573e14 Mesh: Move face shade smooth flag to a generic attribute
Currently the shade smooth status for mesh faces is stored as part of
`MPoly::flag`. As described in #95967, this moves that information
to a separate boolean attribute. It also flips its status, so the
attribute is now called `sharp_face`, which mirrors the existing
`sharp_edge` attribute. The attribute doesn't need to be allocated
when all faces are smooth. Forward compatibility is kept until
4.0 like the other mesh refactors.

This will reduce memory bandwidth requirements for some operations,
since the array of booleans uses 12 times less memory than `MPoly`.
It also allows faces to be stored more efficiently in the future, since
the flag is now unused. It's also possible to use generic functions to
process the values. For example, finding whether there is a sharp face
is just `sharp_faces.contains(true)`.

The `shade_smooth` attribute is no longer accessible with geometry nodes.
Since there were dedicated accessor nodes for that data, that shouldn't
be a problem. That's difficult to version automatically since the named
attribute nodes could be used in arbitrary combinations.

**Implementation notes:**
- The attribute and array variables in the code use the `sharp_faces`
  term, to be consistent with the user-facing "sharp faces" wording,
  and to avoid requiring many renames when #101689 is implemented.
- Cycles now accesses smooth face status with the generic attribute,
  to avoid overhead.
- Changing the zero-value from "smooth" to "flat" takes some care to
  make sure defaults are the same.
  - Versioning for the edge mode extrude node is particularly complex.
    New nodes are added by versioning to propagate the attribute in its
    old inverted state.
- A lot of access is still done through the `CustomData` API rather
  than the attribute API because of a few functions. That can be
  cleaned up easily in the future.
- In the future we would benefit from a way to store attributes as a
  single value for when all faces are sharp.

Pull Request: https://projects.blender.org/blender/blender/pulls/104422
2023-03-08 15:36:18 +01:00
Germano Cavalcante
7fcb262dfd Cleanup: resolve some unreferenced parameter warnings in MSVC
When the warning level is set to 4, some unreferenced parameter
warnings can appear

This commit resolves some of those warnings.
2023-03-07 21:39:44 -03:00
Hans Goudey
3022a805ca Cleanup: Standardize mesh edge and poly naming
With the goal of clearly differentiating between arrays and single
elements, improving consistency across Blender, and using wording
that's easier to read and say, change variable names for Mesh edges
and polygons/faces.

Common renames are the following, with some extra prefixes, etc.
 - `mpoly` -> `polys`
 - `mpoly`/`mp`/`p` -> `poly`
 - `medge` -> `edges`
 - `med`/`ed`/`e` -> `edge`

`MLoop` variables aren't affected because they will be replaced
when they're split up into to arrays in #104424.
2023-03-01 15:58:01 -05:00
Hans Goudey
cccf91ff83 Mesh: Move edge UV seams to a generic attribute
As part of #95966, move the `ME_SEAM` flag on mesh edges
to a generic boolean attribute, called `.uv_seam`. This is the
last bit of extra information stored in mesh edges. After this
is committed we can switch to a different type for them and
have a 1/3 improvement in memory consumption.

It is also now possible to see that a mesh has no UV seams in
constant time, and like other similar refactors, interacting with
only the UV seams can be done with less memory.

The attribute name starts with a `.` to signify that the attribute,
like face sets, isn't meant to be used in arbitrary procedural
situations (with geometry nodes for example). That gives us more
freedom to change things in the future.

Pull Request #104728
2023-03-01 14:13:05 +01:00
Hans Goudey
b37111c574 Cleanup: Use consistent "vert" term for mesh normals
Use "vert" instead of "vertex" when referring to mesh normals. This was
discussed as part of 1af62cb3bf but never completely
implemented.
2023-02-27 15:52:29 -05:00
Joseph Eagar
3e049973ee BMesh: fix invalid existence check in BM_mesh_bm_to_me
Remember that the null customdata layer index is -1,
not 0.
2023-02-20 17:46:45 -08:00
Julian Eisel
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
Julian Eisel
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
YimingWu
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
Dalai Felinto
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
Dalai Felinto
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
Hans Goudey
4ebb66864a Fix #104826: Mesh to BMesh with shape keys can corrupt layers
The custom data layer mappings from dfacaf4f40 were created
*before* the BMesh shape key layers were added, invalidating the BMesh
data offsets they stored. Fix by creating the mappings after all layers
have been created.
2023-02-16 16:30:59 -05:00
Campbell Barton
818c16ef1f Cleanup: pass a const argument to CustomData_get_elem_size 2023-02-14 12:26:01 +11:00
Campbell Barton
0fa34aa0ec Cleanup: spelling in comments, reference enum types in doc-strings
Also use doxy formatting for structs in sculpt_uv.c.
2023-02-14 10:29:48 +11:00
Hans Goudey
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
Martijn Versteegh
1e794d9a92 BMesh: Add flexibility for future lazily created UV selection
Don't crash on nonexisting uv selection layers. Add an assert
because for now it is a bug if they don't exist. But when converting
back to Mesh it is preferable to accept in release mode, as opposed to
crashing.

Pull Request #104600
2023-02-13 20:08:30 +01:00
Martijn Versteegh
684789c815 Fix #104501: Clear CD_FLAG_NOCOPY after use
When generating a Mesh from a BMesh the uv map bool layers are not
copied if all elements are false. To suppress the copying the flag
CD_FLAG_NOCOPY is set in the layer flags. However these layers *do*
need to be copied to other BMeshes (for example undo steps). So we
need to clear them afterwards.
2023-02-13 20:08:29 +01:00
Campbell Barton
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
Campbell Barton
ce44953933 Cleanup: various C++ cleanups 2023-02-11 14:04:35 +11:00
Joseph Eagar
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
Hans Goudey
7ca651d182 Mesh: Remove unnecessary edge draw flag
As described in #95966, replace the `ME_EDGEDRAW` flag with a bit
vector in mesh runtime data. Currently the the flag is only ever set
to false for the "optimal display" feature of the subdivision surface
modifier. When creating an "original" mesh in the main data-base,
the flag is always supposed to be true.

The bit vector is now created by the modifier only as necessary, and
is cleared for topology-changing operations. This fixes incorrect
interpolation of the flag as noted in #104376. Generally it isn't
possible to interpolate it through topology-changing operations.

After this, only the seam status needs to be removed from edges before
we can replace them with the generic `int2` type (or something similar)
and reduce memory usage by 1/3.

Related:
- 10131a6f62
- 145839aa42

In the future `BM_ELEM_DRAW` could be removed as well. Currently it is
used and aliased by other defines in some non-obvious ways though.

Pull Request #104417
2023-02-09 15:56:05 +01:00
Campbell Barton
0381fe7bfe Cleanup: update username in code-comments: campbellbarton -> ideasman42
Gitea migration changed my username, update code-comments.
2023-02-09 11:33:48 +11:00
Campbell Barton
731c3efd97 Cleanup: format 2023-02-06 12:32:45 +11:00
Hans Goudey
1195933ada Fix: Compile error after BMesh conversion commit 2023-02-03 11:09:19 -05:00
Hans Goudey
ebe8f8ce71 BMesh: Parallelize BMesh to evaluated Mesh conversion
Currently this conversion (which happens when using modifiers in edit
mode, for example) is completely single threaded. It's harder than some
other areas to multithread because BMesh elements don't always know
their indices (and vise versa), and because the dynamic AoS format
used by BMesh makes some typical solutions not helpful.

This patch proposes to split the operation into two steps. The first
updates the indices of BMesh elements and builds tables for easy
iteration later. It also checks if some optional mesh attributes
should be added. The second uses parallel loops over all elements,
copying attribute values and building the Mesh topology.

Both steps process different domains in separate threads (though the
first has to combine faces and loops). Though this isn't proper data
parallelism, it's quite helpful because each domain doesn't affect the
others.

**Timings**
I tested this on a Ryzen 7950x with a 1 million face grid, with no
extra attributes and then with several color attributes and vertex
groups.

| File | Before | After |
| Simple | 101.6 ms | 59.6 ms |
| More Attributes | 149.2 ms | 65.6 ms |

The optimization scales better with more attributes on the BMesh. The
speedup isn't as linear as multithreading other operations, indicating
added overhead. I think this is worth it though, because the user is
usually actively interacting with a mesh in edit mode.

See the differential revision for more timing information.

Differential Revision: https://developer.blender.org/D16249
2023-02-03 10:20:19 -05:00
Campbell Barton
266d8de687 Cleanup: spelling in comments 2023-02-03 12:41:01 +11:00
Campbell Barton
27b4916b1a Cleanup: spelling in comments
Also minor changes in comments:
- Reference BLENDER_HISTORY_FILE instead of the literal file-name
  (simplifies looking up usage).
- Use usernames in tags, as noted in code-style.
2023-01-31 14:22:23 +11:00
Colin Basnett
328772f2d9 Mesh: Add operator to flip quad tessellation
This adds a new operator: bpy.ops.mesh.flip_quad_tessellation()

This operator rotates the internal loops of the selected quads, allowing
the user to control tessellation without destructively altering the
mesh.

{F14201995}

This operator can be found in the "Face" menu (Ctrl+F) under "Face
Data".

{F14201997}

Reviewed By: campbellbarton, dbystedt

Differential Revision: https://developer.blender.org/D17056
2023-01-27 11:02:55 -08:00
Chris Blackbourn
2b4bafeac6 UV: add "similar object" and "similar winding" to uv "select similar"
Adds new options to UV Face selection in the UV Editor, with UV > Select > Select Similar

In multi object edit mode, "Similar Object" selects faces which have the same object.

"Similar Winding" will select faces which have the same winding, i.e. are they
facing upwards or downwards.

Resolves: T103975
Differential Revision: https://developer.blender.org/D17125
2023-01-27 17:58:07 +13:00
Howard Trickey
b544199c56 Fix T102532: bevel spikes with loop slide.
There's a compromise of a code parameter called BEVEL_GOOD_ANGLE,
and bugs T44961, T86768, T95335, and this one, are all about problems
with various values of that parameter. If an angle of an adjacent
non-beveled edge is too close to that of the beveled edge, then you
get spikes. The BEVEL_GOOD_ANGLE says that if you are within that
angle difference, then no bevel happens. If the value is too small
then one gets spikes for certain models people build; if the value
is too large, then other people are annoyed that no bevel happens.
Hopefully this compromise in this commit is the final one I will do
before switching to Bevel v2, where none of this should be an issue.
2023-01-22 10:34:28 -05:00
Campbell Barton
844cca9984 Cleanup: spelling in comments 2023-01-20 15:19:32 +11:00
Campbell Barton
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
Campbell Barton
8b7d2d8eb2 CMake: use BULLET_LIBRARIES for both extern_bullet and system libraries
There was no need to differentiate between these and it made
the CMake files more verbose.
2023-01-19 17:10:42 +11:00
Campbell Barton
60d9de767d Cleanup: remove redundant forward declarations for structs 2023-01-18 18:41:13 +11:00
Hans Goudey
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
Damien Picard
30c90f0ad0 Cleanup: Replace "UV's" with "UVs"
An apostrophe should not be used because it is not a mark of plural,
even for initialisms. This involves mostly comments, but a few UI
messages are affected as well.

Differential Revision: https://developer.blender.org/D16749
2023-01-10 14:50:13 -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
Hans Goudey
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