For copy-on-write, we want to share attribute arrays between meshes
where possible. Mutable pointers like `Mesh.mvert` make that difficult
by making ownership vague. They also make code more complex by adding
redundancy.
The simplest solution is just removing them and retrieving layers from
`CustomData` as needed. Similar changes have already been applied to
curves and point clouds (e9f82d3dc7, 410a6efb74). Removing use of
the pointers generally makes code more obvious and more reusable.
Mesh data is now accessed with a C++ API (`Mesh::edges()` or
`Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`).
The CoW changes this commit makes possible are described in T95845
and T95842, and started in D14139 and D14140. The change also simplifies
the ongoing mesh struct-of-array refactors from T95965.
**RNA/Python Access Performance**
Theoretically, accessing mesh elements with the RNA API may become
slower, since the layer needs to be found on every random access.
However, overhead is already high enough that this doesn't make a
noticible differenc, and performance is actually improved in some
cases. Random access can be up to 10% faster, but other situations
might be a bit slower. Generally using `foreach_get/set` are the best
way to improve performance. See the differential revision for more
discussion about Python performance.
Cycles has been updated to use raw pointers and the internal Blender
mesh types, mostly because there is no sense in having this overhead
when it's already compiled with Blender. In my tests this roughly
halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million
face grid).
Differential Revision: https://developer.blender.org/D15488
This patch moves material indices from the mesh `MPoly` struct to a
generic integer attribute. The builtin material index was already
exposed in geometry nodes, but this makes it a "proper" attribute
accessible with Python and visible in the "Attributes" panel.
The goals of the refactor are code simplification and memory and
performance improvements, mainly because the attribute doesn't have
to be stored and processed if there are no materials. However, until
4.0, material indices will still be read and written in the old
format, meaning there may be a temporary increase in memory usage.
Further notes:
* Completely removing the `MPoly.mat_nr` after 4.0 may require
changes to DNA or introducing a new `MPoly` type.
* Geometry nodes regression tests didn't look at material indices,
so the change reveals a bug in the realize instances node that I fixed.
* Access to material indices from the RNA `MeshPolygon` type is slower
with this patch. The `material_index` attribute can be used instead.
* Cycles is changed to read from the attribute instead.
* BMesh isn't changed in this patch. Theoretically it could be though,
to save 2 bytes per face when less than two materials are used.
* Eventually we could use a 16 bit integer attribute type instead.
Ref T95967
Differential Revision: https://developer.blender.org/D15675
The number of attribute domains isn't an attribute domain, so storing
ATTR_DOMAIN_NUM in a variable with an eAttrDomain type isn't correct.
In the cases it was used, the value wouldn't be accessed anyway.
This commit moves the hide status of mesh vertices, edges, and faces
from the `ME_FLAG` to optional generic boolean attributes. Storing this
data as generic attributes can significantly simplify and improve code,
as described in T95965.
The attributes are called `.hide_vert`, `.hide_edge`, and `.hide_poly`,
using the attribute name semantics discussed in T97452. 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 by default,
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 the hide status is used. When the flags are removed
completely, requirements will decrease when hiding is unused.
Further notes:
* Some code can be further simplified to skip some processing when the
hide attributes don't exist.
* The data is still stored in flags for `BMesh`, necessitating some
complexity in the conversion to and from `Mesh`.
* Access to the "hide" property of mesh elements in RNA is slower.
The separate boolean arrays should be used where possible.
Ref T95965
Differential Revision: https://developer.blender.org/D14685
Instead of passing pointers to specific mesh data, rely on
retrieving that data from the mesh internally. This makes
it easier to support retrieving additional data from Mesh
(like active attribute names in D15101 or D15169). It also makes
the functions simpler conceptually, because they're drawing
a mesh with an acceleration strcture on top.
The BKE_id_attribute_copy_domains_temp call was unnecessary
because the GPU_pbvh_mesh_buffers_update function was only
called when Mesh/PBVH_FACES is used in the first place.
Differential Revision: https://developer.blender.org/D15197
This patch adds support for PBVH drawing in EEVEE.
Notes:
# PBVH_FACES only. For Multires we'll need an API to get/cache attributes. DynTopo support will be merged in later with sculpt-dev's DynTopo implementation.
# Supports vertex color and UV attributes only; other types can be added fairly easily though.
# Workbench only sends the active vertex color and UV layers to the GPU.
# Added a new draw engine API method, DRW_cdlayer_attr_aliases_add. Please review.
# The vertex format object is now stored in the pbvh.
Reviewed By: Clément Foucault & Brecht Van Lommel & Jeroen Bakker
Differential Revision: https://developer.blender.org/D13897
Ref D13897
The "PROP" in the name reflects its generic status, and removing
"LOOP" makes sense because it is no longer associated with just
mesh face corners. In general the goal is to remove extra semantic
meaning from the custom data types.
color attribute system.
This commit removes sculpt colors from experimental
status and unifies it with vertex colors. It
introduces the concept of "color attributes", which
are any attributes that represents colors. Color
attributes can be represented with byte or floating-point
numbers and can be stored in either vertices or
face corners.
Color attributes share a common namespace
(so you can no longer have a floating-point
sculpt color attribute and a byte vertex color
attribute with the same name).
Note: this commit does not include vertex paint mode,
which is a separate patch, see:
https://developer.blender.org/D14179
Differential Revision: https://developer.blender.org/D12587
Ref D12587
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
As described in T91186, this commit moves mesh vertex normals into a
contiguous array of float vectors in a custom data layer, how face
normals are currently stored.
The main interface is documented in `BKE_mesh.h`. Vertex and face
normals are now calculated on-demand and cached, retrieved with an
"ensure" function. Since the logical state of a mesh is now "has
normals when necessary", they can be retrieved from a `const` mesh.
The goal is to use on-demand calculation for all derived data, but
leave room for eager calculation for performance purposes (modifier
evaluation is threaded, but viewport data generation is not).
**Benefits**
This moves us closer to a SoA approach rather than the current AoS
paradigm. Accessing a contiguous `float3` is much more efficient than
retrieving data from a larger struct. The memory requirements for
accessing only normals or vertex locations are smaller, and at the
cost of more memory usage for just normals, they now don't have to
be converted between float and short, which also simplifies code
In the future, the remaining items can be removed from `MVert`,
leaving only `float3`, which has similar benefits (see T93602).
Removing the combination of derived and original data makes it
conceptually simpler to only calculate normals when necessary.
This is especially important now that we have more opportunities
for temporary meshes in geometry nodes.
**Performance**
In addition to the theoretical future performance improvements by
making `MVert == float3`, I've done some basic performance testing
on this patch directly. The data is fairly rough, but it gives an idea
about where things stand generally.
- Mesh line primitive 4m Verts: 1.16x faster (36 -> 31 ms),
showing that accessing just `MVert` is now more efficient.
- Spring Splash Screen: 1.03-1.06 -> 1.06-1.11 FPS, a very slight
change that at least shows there is no regression.
- Sprite Fright Snail Smoosh: 3.30-3.40 -> 3.42-3.50 FPS, a small
but observable speedup.
- Set Position Node with Scaled Normal: 1.36x faster (53 -> 39 ms),
shows that using normals in geometry nodes is faster.
- Normal Calculation 1.6m Vert Cube: 1.19x faster (25 -> 21 ms),
shows that calculating normals is slightly faster now.
- File Size of 1.6m Vert Cube: 1.03x smaller (214.7 -> 208.4 MB),
Normals are not saved in files, which can help with large meshes.
As for memory usage, it may be slightly more in some cases, but
I didn't observe any difference in the production files I tested.
**Tests**
Some modifiers and cycles test results need to be updated with this
commit, for two reasons:
- The subdivision surface modifier is not responsible for calculating
normals anymore. In master, the modifier creates different normals
than the result of the `Mesh` normal calculation, so this is a bug
fix.
- There are small differences in the results of some modifiers that
use normals because they are not converted to and from `short`
anymore.
**Future improvements**
- Remove `ModifierTypeInfo::dependsOnNormals`. Code in each modifier
already retrieves normals if they are needed anyway.
- Copy normals as part of a better CoW system for attributes.
- Make more areas use lazy instead of eager normal calculation.
- Remove `BKE_mesh_normals_tag_dirty` in more places since that is
now the default state of a new mesh.
- Possibly apply a similar change to derived face corner normals.
Differential Revision: https://developer.blender.org/D12770
This removes the limitation of the sculpt overlays not being visible
with modifiers active.
Reviewed By: fclem
Maniphest Tasks: T68900
Differential Revision: https://developer.blender.org/D8673
This disables all Sculpt Vertex Colors tools, operators, panels and rendering capabilities and puts them under the "Use Sculpt Vertex Colors" experimental option.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D8239
The face sets color copy to the GPU was done outside of the loop,
probably after a merge error in a rebase.
Also, the default color was initialized using the wrong type.
Reviewed By: sergey
Maniphest Tasks: T78188
Differential Revision: https://developer.blender.org/D8106
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
When the number of triangles in a node became zero, the wireframe batch was
not freed along with the triangles batch and could still reference a freed
vertex buffer.
Ref T76858
This removes the smooth shading rendering from the face set overlay when
smooth shading is enabled.
Reviewed By: jbakker
Maniphest Tasks: T74906, T74622, T75331, T76530
Differential Revision: https://developer.blender.org/D7105
These values were hardcoded before Face Sets were enabled for Multires,
so enable the show_face_sets checks now.
Reviewed By: jbakker
Maniphest Tasks: T75329
Differential Revision: https://developer.blender.org/D7444
This implements the Sculpt Mode API functions needed for Face Sets and
visibility management for PBVH_GRIDS. No major changes were needed in
the operators and the sculpt mode code. This implementation stores the
face sets in the base mesh, so faces created in higher subdivision
levels can't be modified individually. Also, we are not checking for
multiple face sets per vertex (that can be added in the future), so
relax tools don't work yet. The rest of the features (paint, undo,
visibility operators..) work as expected.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D7168
Using a float to store and render the mask seems like a waste of memory
without any noticeable difference in the viewport for its use case.
After this commit, the mask and the face sets combined should take the
same amount of GPU memory than only the mask in previous versions.
Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D7148
SCULPT_FACE_SET_NONE default value is 0 and it is rendered hidden, so
the invert sign operation to show it was not working. Now the show all
function sets this face set to ID 1 before setting its sign.
I also refactored this check in gpu_buffers.
Not related to the reported issue, but the mesh in attached contains non
manifold geometry with hidden loose vertices, so the visibility state
was not syncing correctly to those vertices. Now the toggle operators
checks the current visibility only on the face sets, so no manifold
vertices are ignored (as they are in the rest of operations in sculpt
mode).
Reviewed By: jbakker
Maniphest Tasks: T74780
Differential Revision: https://developer.blender.org/D7188
The default face set color is white, so we can skip drawing the default
face set. This allows to enable again the optimization of not drawing
overlays in nodes where the mask is empty.
This will still slow down the viewport when a new face set is created
for the whole mesh or when inverting the mask, like in previous
versions.
I also renamed the function to make more clear that now it is checking
for both mask and face sets.
Reviewed By: brecht
Maniphest Tasks: T74692
Differential Revision: https://developer.blender.org/D7207
The face set color variable needs to be declared inside of the loop in
order to reset it per iteration.
Reviewed By: jbakker
Maniphest Tasks: T74626
Differential Revision: https://developer.blender.org/D7096
The face set ID is sequential, so implementing this was straightforward.
Suggested by Jeroen Bakker
Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D7123
This introduces a variable to store a face set ID which is going to be
rendered white. When initializing a mesh or randomizing the colors, this
variable gets updated to always render a white face set. This way the
face set overlay can be enabled without adding colors to the mesh if
face sets are not in use. After creating the first face set, new colors
are generated randomly like usual.
The face set stored as default does not have any special meaning for
tools or brushes, it just affects the rendering color.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D7035
This way we can change the color generation easily if we want to improve
it in the future. I also added more values to randomize a little bit the
saturation and value of the colors, as previously it was too easy to get
similar colors when creating new faces, forcing you to use the randomize
colors more than necessary.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D7042
Apparently this happened when the object is in a flat view and has
customdata `CD_SCULPT_FACE_SETS`
Differential Revision: https://developer.blender.org/D7073
While it might be handy to have type-less functionality which is
similar to how C++ math is implemented it can not be easily achieved
with just preprocessor in a way which does not have side-effects on
wrong usage.
There macros where often used on a non-trivial expression, and there
was at least one usage where it was causing an actual side effect/bug
on Windows (see change around square_f(sh[index++]) in studiolight.c).
For such cases it is handy to have a function which is guaranteed to
have zero side-effects. The motivation behind actually removing the
macros is that there is already a way to do similar calculation. Also,
not having such macros is a way to guarantee that its usage is not
changed in a way which have side-effects and that it's not used as an
inspiration for cases where it should not be used.
Differential Revision: https://developer.blender.org/D7051
Face Sets are the new system to control the visibility state of the mesh in sculpt and paint modes. They are designed to work in modes where brushes are the primary way of interaction and they provide much more control when working with meshes with complex shapes and overlapping surfaces.
This initial commit includes:
- Sculpt Face Sets data structures and PBVH rendering.
- Face Set overlay and opacity controls.
- Sculpt Undo support.
- Remesher reprojection support. The visibility state of the mesh is also preserved when remeshing.
- Automasking and Mesh filter support.
- Mask expand operator mode to expand Face Sets (Shift + W) and flood fill areas by connectivity (press Ctrl while expanding).
- Sculpt Mode Face Sets and Visibility API.
- Sculpt Face Sets creation and visibility management operators.
- Operator to randomize the Face Sets colors.
- Draw Face Sets brush tool to create and edit the Face Sets. Drawing on the mesh creates a new Face Set. Pressing Ctrl before drawing modifies the Face Set under the brush at the beginning of the stroke.
- Updated keymap and menu to work with Face Sets from Sculpt Mode (H to toggle visibility, Alt + H to show all, Shit + H to hide).
- Pie menu on the W key with Face common Sets operations.
Know limitations:
- Multires support. The Face Sets and Visibility API needs to be implemented for Multires.
Reviewed By: jbakker, #user_interface, Severin
Differential Revision: https://developer.blender.org/D6070
This way we remove the need for the srgb boolean uniform and a lot of code complexity. However, mesh update is going to be a bit slower.
I did not benchmark the performance impact.
This also fix a typo in draw_cache_impl_particles.c and fix hair not using vertex color in workbench.
Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D6610
With this commit sculpt mode draws the real mesh wireframe instead of the
triangulated version by ignoring non real edges when building the PBVH GPU buffers
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D6032