Commit Graph

19 Commits

Author SHA1 Message Date
Hans Goudey
1850a0b2ab Mesh: Avoid creating incorrect original index layers
Currently, whenever any BMesh is converted to a Mesh (except for edit
mode switching), original index (`CD_ORIGINDEX`) layers are added.
This is incorrect, because many operations just convert some Mesh into
a BMesh and then back, but they shouldn't make any assumption about
where their input mesh came from. It might even come from a primitive
in geometry nodes, where there are no original indices at all.

Conceptually, mesh original indices should be filled by the modifier
stack when first creating the evaluated mesh. So that's where they're
moved in this patch. A separate function now fills the indices with their
default (0,1,2,3...) values. The way the mesh wrapper system defers
the BMesh to Mesh conversion makes this a bit less obvious though.

The old behavior is incorrect, but it's also slower, because three
arrays the size of the mesh's vertices, edges, and faces had to be
allocated and filled during the BMesh to Mesh conversion, which just
ends up putting more pressure on the cache. In the many cases where
original indices aren't used, I measured an **8% speedup** for the
conversion (from 76.5ms to 70.7ms).

Generally there is an assumption that BMesh is "original" and Mesh is
"evaluated". After this patch, that assumption isn't quite as strong,
but it still exists for two reasons. First, original indices are added
whenever converting a BMesh "wrapper" to a Mesh. Second, original
indices are not added to the BMesh at the beginning of evaluation,
which assumes that every BMesh in the viewport is original and doesn't
need the mapping.

Differential Revision: https://developer.blender.org/D14018
2022-02-18 10:51:00 -06:00
Kévin Dietrich
cc6ddfbf68 Merge remote-tracking branch 'origin/blender-v3.1-release' 2022-02-11 13:48:09 +01:00
Kévin Dietrich
2496a94384 Fix T95698: deadlock with GPU subdivision
Multithreaded tasks have to be isolated when holding a mutex, which was
missing for the generation of the subdivision wrapper.
2022-02-11 13:45:12 +01:00
Campbell Barton
c434782e3a File headers: SPDX License migration
Use a shorter/simpler license convention, stops the header taking so
much space.

Follow the SPDX license specification: https://spdx.org/licenses

- C/C++/objc/objc++
- Python
- Shell Scripts
- CMake, GNUmakefile

While most of the source tree has been included

- `./extern/` was left out.
- `./intern/cycles` & `./intern/atomic` are also excluded because they
  use different header conventions.

doc/license/SPDX-license-identifiers.txt has been added to list SPDX all
used identifiers.

See P2788 for the script that automated these edits.

Reviewed By: brecht, mont29, sergey

Ref D14069
2022-02-11 09:14:36 +11:00
Kévin Dietrich
f134341e03 Fix T94671: performance regression with subsurf modifier
rBeed45d2a239a introduced a GPU backend for OpenSubDiv which lets us do
the subdivision at render time. However, some tools might still need to
have the subdivision data available on the CPU side. For this a
subdivision mesh wrapper was also introduced, and is computed whenever a
CPU side mesh is needed. The subdivision settings for this wrapper are
stored during modifier evaluation if GPU subdivision can be done.

The performance regression is due to the fact that although the
subdivision mesh was already computed on the CPU, and no subdivision
wrapper is generated, some checks for creating subdivision data in
`BKE_mesh_wrapper_ensure_subdivision` where still run, one of which is
very expensive.

To fix this we first check the runtime settings of the mesh to see if
subdivision is needed at all.
2022-01-11 03:34:16 +01:00
Kévin Dietrich
d25fa3250a Fix T94420: deadlock with subsurf modifiers
The deadlock was caused as the lock on the Mesh mutex used to compute
the subdivision wrapper was not released in some early exits of the
function.
2021-12-28 09:20:17 +01:00
Kévin Dietrich
eed45d2a23 OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.

When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).

This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.

We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.

In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.

Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).

See patch description for benchmarks.

Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport

Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:35:54 +01:00
Campbell Barton
a8739ae6c2 Fix regression in recent change 0708733c46
Adding a mirror modifier in edit-mode crashed.

Freeing meshes that hold a shallow copy happens in multiple places
while calculating modifiers, making it impractical to clear the
edit-mode pointer before freeing the mesh (as done in
BKE_editmesh_free_derived_caches).

Add a struct member to the edit-mesh struct so evaluated copies
don't free the edit-mesh contents.
2021-09-02 16:12:24 +10:00
Campbell Barton
a2f3aca647 Cleanup: remove redundant edit-mesh memory allocation
This memory was only duplicated to satisfy mesh_data_free
which was incorrectly freeing the pointer (but nothing else).
2021-09-02 15:30:54 +10:00
Brecht Van Lommel
026de343e3 Fix deadlock with shrinkwrap and other modifiers
More code that needs task isolation. Encountered in sprite fright production
file.

Ref D11603
2021-06-22 18:26:58 +02:00
Campbell Barton
6db290641e Cleanup: split BKE_mesh_copy_settings into two functions
- BKE_mesh_copy_parameters_for_eval to be used for evaluated meshes only
  as it doesn't handle ID user-counts.

- BKE_mesh_copy_parameters is a general function for copying parameters
  between meshes.
2021-06-17 15:08:19 +10:00
Campbell Barton
3f47df577d Cleanup: use new BLI_assert_unreachable macro 2021-03-24 12:38:08 +11:00
Bastien Montagne
4e6975ffd6 Fix T78285: Invalid thread safety in shrinkwrap modifier code.
This uses mesh's runtime mutex for both `BKE_mesh_runtime_looptri_ensure`
(was using its own global RW mutex before), and `BKE_mesh_wrapper_ensure_mdata`
(was not protected at all before).

This is more like a band-aid than a proper fix, as mentioned in the report
proper fix would be for the modifier to request those data (the relevant
BVHTree, which would implicitely also call the tow others) through flags,
just like it does for regular CDData layers. But this is a much bigger
refactor to be done outside of bugfix scope.

Reviewed By: sergey

Maniphest Tasks: T78285

Differential Revision: https://developer.blender.org/D8415
2020-07-29 17:36:46 +02:00
Campbell Barton
f79856f9fb Cleanup: minor changes to deform functions
- Use 'float (*)[3]' to avoid casts.
- Remove unnecessary float[3] copy in gpencil_deform_verts.
- Use MEM_SAFE_FREE
- Use const arguments.
2020-06-12 14:39:49 +10:00
Campbell Barton
75ce20a000 Cleanup: redundant headers 2020-06-10 22:34:11 +10:00
Campbell Barton
0ca0ad5318 Cleanup: move BKE_mesh_wrapper functions into own header 2020-06-10 22:34:11 +10:00
Campbell Barton
a4bb4b6e65 Mesh: utility functions to access wrapped mesh coordinates 2020-06-10 15:54:00 +10:00
Bastien Montagne
1b06d5742e Fix building after rBdeaff945d0b9... sic. 2020-05-25 16:07:37 +02:00
Campbell Barton
deaff945d0 Mesh: skip conversion from edit-mesh to mesh in edit-mode
This resolves a performance regression in 2.8x where every edit-mode
update performed an edit-mesh to mesh conversion.

Now the conversion will be lazily initialized if/when it's required.

New BKE_mesh_wrapper_* functions abstract over mesh data access.
Currently only edit-mesh and regular meshes are supported.
In the future sub-surface meshes may be supported too.
2020-05-25 23:07:30 +10:00