Cleanup: Sculpt: Avoid unnecessarily changing vertex normals #111470

Merged
Hans Goudey merged 3 commits from HooglyBoogly/blender:remove-sculpt-normal-reference into main 2023-08-24 16:48:02 +02:00
4 changed files with 12 additions and 17 deletions

View File

@ -499,7 +499,7 @@ struct PBVHVertexIter {
/* mesh */
blender::MutableSpan<blender::float3> vert_positions;
blender::MutableSpan<blender::float3> vert_normals;
blender::Span<blender::float3> vert_normals;
const bool *hide_vert;
int totvert;
const int *vert_indices;
@ -516,8 +516,8 @@ struct PBVHVertexIter {
* that compiler optimization's will skip the ones we don't use */
BMVert *bm_vert;
float *co;
float *no;
float *fno;
const float *no;
const float *fno;
float *mask;
bool visible;
};

View File

@ -1296,7 +1296,7 @@ static bool update_search(PBVHNode *node, const int flag)
return true;
}
static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
{
using namespace blender;
using namespace blender::bke;
@ -1319,17 +1319,16 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
return;
}
MutableSpan<float3> vert_normals = pbvh->vert_normals;
MutableSpan<float3> face_normals = pbvh->face_normals;
VectorSet<int> verts_to_update;
threading::parallel_invoke(
[&]() {
MutableSpan<float3> face_normals = mesh.runtime->face_normals;
threading::parallel_for(faces_to_update.index_range(), 512, [&](const IndexRange range) {
for (const int i : faces_to_update.as_span().slice(range)) {
face_normals[i] = mesh::face_normal_calc(positions, corner_verts.slice(faces[i]));
}
});
mesh.runtime->face_normals_dirty = false;
},
[&]() {
/* Update all normals connected to affected faces, even if not explicitly tagged. */
@ -1346,6 +1345,8 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
}
});
const Span<float3> face_normals = mesh.runtime->face_normals;
MutableSpan<float3> vert_normals = mesh.runtime->vert_normals;
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);
@ -1355,6 +1356,7 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes)
vert_normals[vert] = math::normalize(normal);
}
});
mesh.runtime->vert_normals_dirty = false;
}
static void node_update_mask_redraw(PBVH &pbvh, PBVHNode &node)
@ -2849,7 +2851,7 @@ void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg)
pbvh_bmesh_normals_update(nodes);
}
else if (pbvh->header.type == PBVH_FACES) {
pbvh_faces_update_normals(pbvh, nodes);
pbvh_faces_update_normals(pbvh, nodes, *pbvh->mesh);
}
else if (pbvh->header.type == PBVH_GRIDS) {
CCGFace **faces;

View File

@ -151,9 +151,8 @@ struct PBVH {
/* Mesh data */
Mesh *mesh;
/* NOTE: Normals are not `const` because they can be updated for drawing by sculpt code. */
blender::MutableSpan<blender::float3> vert_normals;
blender::MutableSpan<blender::float3> face_normals;
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. */

View File

@ -1564,12 +1564,6 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
SCULPT_orig_vert_data_update(&orig_vert_data, &vd);
copy_v3_v3(vd.co, orig_vert_data.co);
if (vd.no) {
copy_v3_v3(vd.no, orig_vert_data.no);
}
else {
copy_v3_v3(vd.fno, orig_vert_data.no);
}
if (vd.is_mesh) {
BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex);
}