Merge branch 'blender-v4.0-release'

This commit is contained in:
Campbell Barton
2023-10-25 15:43:13 +11:00
2 changed files with 77 additions and 36 deletions

View File

@@ -805,17 +805,15 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh)
pbvh->looptri_faces = mesh->looptri_faces();
if (!pbvh->deformed) {
/* Deformed positions not matching the original mesh are owned directly by the PBVH, and are
/* Deformed data not matching the original mesh are owned directly by the PBVH, and are
* set separately by #BKE_pbvh_vert_coords_apply. */
pbvh->vert_positions = mesh->vert_positions_for_write();
pbvh->vert_normals = mesh->vert_normals();
pbvh->face_normals = mesh->face_normals();
}
BKE_pbvh_update_hide_attributes_from_mesh(pbvh);
/* Make sure cached normals start out calculated. */
pbvh->vert_normals = mesh->vert_normals();
pbvh->face_normals = mesh->face_normals();
pbvh->vert_data = &mesh->vert_data;
pbvh->loop_data = &mesh->loop_data;
pbvh->face_data = &mesh->face_data;
@@ -1276,6 +1274,38 @@ static bool update_search(PBVHNode *node, const int flag)
return true;
}
static void normals_calc_faces(const Span<float3> positions,
const blender::OffsetIndices<int> faces,
const Span<int> corner_verts,
const Span<int> mask,
MutableSpan<float3> face_normals)
{
using namespace blender;
using namespace blender::bke;
threading::parallel_for(mask.index_range(), 512, [&](const IndexRange range) {
for (const int i : mask.slice(range)) {
face_normals[i] = mesh::face_normal_calc(positions, corner_verts.slice(faces[i]));
}
});
}
static void normals_calc_verts_simple(const blender::GroupedSpan<int> vert_to_face_map,
const Span<float3> face_normals,
const Span<int> mask,
MutableSpan<float3> vert_normals)
{
using namespace blender;
threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) {
for (const int vert : mask.slice(range)) {
float3 normal(0.0f);
for (const int face : vert_to_face_map[vert]) {
normal += face_normals[face];
}
vert_normals[vert] = math::normalize(normal);
}
});
}
static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
{
using namespace blender;
@@ -1302,13 +1332,17 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes, Mesh &
VectorSet<int> verts_to_update;
threading::parallel_invoke(
[&]() {
mesh.runtime->face_normals_cache.update([&](Vector<float3> &r_data) {
threading::parallel_for(faces_to_update.index_range(), 512, [&](const IndexRange range) {
for (const int i : faces_to_update.as_span().slice(range)) {
r_data[i] = mesh::face_normal_calc(positions, corner_verts.slice(faces[i]));
}
if (pbvh->deformed) {
normals_calc_faces(
positions, faces, corner_verts, faces_to_update, pbvh->face_normals_deformed);
}
else {
mesh.runtime->face_normals_cache.update([&](Vector<float3> &r_data) {
normals_calc_faces(positions, faces, corner_verts, faces_to_update, r_data);
});
});
/* #SharedCache::update() reallocates cached vectors if they were shared initially. */
pbvh->face_normals = mesh.runtime->face_normals_cache.data();
}
},
[&]() {
/* Update all normals connected to affected faces, even if not explicitly tagged. */
@@ -1325,22 +1359,16 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes, Mesh &
}
});
const Span<float3> face_normals = mesh.face_normals();
mesh.runtime->vert_normals_cache.update([&](Vector<float3> &r_data) {
threading::parallel_for(verts_to_update.index_range(), 1024, [&](const IndexRange range) {
for (const int vert : verts_to_update.as_span().slice(range)) {
float3 normal(0.0f);
for (const int face : pbvh->pmap[vert]) {
normal += face_normals[face];
}
r_data[vert] = math::normalize(normal);
}
if (pbvh->deformed) {
normals_calc_verts_simple(
pbvh->pmap, pbvh->face_normals, verts_to_update, pbvh->vert_normals_deformed);
}
else {
mesh.runtime->vert_normals_cache.update([&](Vector<float3> &r_data) {
normals_calc_verts_simple(pbvh->pmap, pbvh->face_normals, verts_to_update, r_data);
});
});
/* #SharedCache::update() reallocates the cached vectors if they were shared initially. */
pbvh->face_normals = mesh.runtime->face_normals_cache.data();
pbvh->vert_normals = mesh.runtime->vert_normals_cache.data();
pbvh->vert_normals = mesh.runtime->vert_normals_cache.data();
}
}
static void node_update_mask_redraw(PBVH &pbvh, PBVHNode &node)
@@ -2967,14 +2995,21 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int
if (!pbvh->deformed) {
if (!pbvh->vert_positions.is_empty()) {
/* if pbvh is not already deformed, verts/faces points to the */
/* original data and applying new coords to this arrays would lead to */
/* unneeded deformation -- duplicate verts/faces to avoid this */
pbvh->vert_positions_deformed = blender::Array<float3>(pbvh->vert_positions.as_span());
/* When the PBVH is deformed, it creates a separate vertex position array that it owns
* directly. Conceptually these copies often aren't and often adds extra indirection, but:
* - Sculpting shape keys, the deformations are flushed back to the keys as a separate step.
* - Sculpting on a deformed mesh, deformations are also flushed to original positions
* separately.
* - The PBVH currently always assumes we want to change positions, and has no way to avoid
* calculating normals if it's only used for painting, for example. */
pbvh->vert_positions_deformed = pbvh->vert_positions.as_span();
pbvh->vert_positions = pbvh->vert_positions_deformed;
/* No need to dupalloc pbvh->looptri, this one is 'totally owned' by pbvh,
* it's never some mesh data. */
pbvh->vert_normals_deformed = pbvh->vert_normals;
pbvh->vert_normals = pbvh->vert_normals_deformed;
pbvh->face_normals_deformed = pbvh->face_normals;
pbvh->face_normals = pbvh->face_normals_deformed;
pbvh->deformed = true;
}

View File

@@ -154,13 +154,19 @@ struct PBVH {
/* Mesh data */
Mesh *mesh;
/** Local array used when not sculpting base mesh positions directly. */
blender::Array<blender::float3> vert_positions_deformed;
/** Local array used when not sculpting base mesh positions directly. */
blender::Array<blender::float3> vert_normals_deformed;
/** Local array used when not sculpting base mesh positions directly. */
blender::Array<blender::float3> face_normals_deformed;
blender::MutableSpan<blender::float3> vert_positions;
blender::Span<blender::float3> vert_normals;
blender::Span<blender::float3> face_normals;
bool *hide_vert;
blender::MutableSpan<blender::float3> vert_positions;
/** Local vertex positions owned by the PVBH when not sculpting base mesh positions directly. */
blender::Array<blender::float3> vert_positions_deformed;
blender::OffsetIndices<int> faces;
bool *hide_vert;
bool *hide_poly;
/** Only valid for polygon meshes. */
blender::Span<int> corner_verts;