Refactor: Remove vert to face map from PBVH storage

Part of an effort to reduce redundancy of storage for data used
by sculpt mode. See #118145.
This commit is contained in:
Hans Goudey
2024-04-29 16:41:59 -04:00
committed by Hans Goudey
parent 8d13a9608b
commit 75e424563c
7 changed files with 54 additions and 43 deletions

View File

@@ -531,6 +531,7 @@ bool BKE_pbvh_get_color_layer(Mesh *mesh,
/* Swaps colors at each element in indices (of domain pbvh->vcol_domain)
* with values in colors. */
void BKE_pbvh_swap_colors(PBVH &pbvh,
blender::GroupedSpan<int> vert_to_face_map,
blender::Span<int> indices,
blender::MutableSpan<blender::float4> r_colors);
@@ -542,6 +543,7 @@ void BKE_pbvh_store_colors(PBVH &pbvh,
/* Like BKE_pbvh_store_colors but handles loop->vert conversion */
void BKE_pbvh_store_colors_vertex(PBVH &pbvh,
blender::GroupedSpan<int> vert_to_face_map,
blender::Span<int> indices,
blender::MutableSpan<blender::float4> r_colors);
@@ -549,14 +551,18 @@ bool BKE_pbvh_is_drawing(const PBVH &pbvh);
void BKE_pbvh_update_active_vcol(PBVH &pbvh, Mesh *mesh);
void BKE_pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float color[4]);
void BKE_pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_color[4]);
void BKE_pbvh_vertex_color_set(PBVH &pbvh,
blender::GroupedSpan<int> vert_to_face_map,
PBVHVertRef vertex,
const float color[4]);
void BKE_pbvh_vertex_color_get(const PBVH &pbvh,
blender::GroupedSpan<int> vert_to_face_map,
PBVHVertRef vertex,
float r_color[4]);
void BKE_pbvh_ensure_node_loops(PBVH &pbvh);
int BKE_pbvh_debug_draw_gen_get(PBVHNode &node);
void BKE_pbvh_pmap_set(PBVH &pbvh, blender::GroupedSpan<int> vert_to_face_map);
namespace blender::bke::pbvh {
Vector<PBVHNode *> search_gather(PBVH &pbvh,
FunctionRef<bool(PBVHNode &)> scb,

View File

@@ -1746,10 +1746,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
ss->vert_to_face_map = mesh_orig->vert_to_face_map();
}
if (ss->pbvh) {
BKE_pbvh_pmap_set(*ss->pbvh, ss->vert_to_face_map);
}
if (ss->deform_modifiers_active) {
/* Painting doesn't need crazyspace, use already evaluated mesh coordinates if possible. */
bool used_me_eval = false;
@@ -2169,7 +2165,6 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
}
BKE_pbvh_update_active_vcol(*ob->sculpt->pbvh, BKE_object_get_original_mesh(ob));
BKE_pbvh_pmap_set(*ob->sculpt->pbvh, ob->sculpt->vert_to_face_map);
return ob->sculpt->pbvh.get();
}
@@ -2192,8 +2187,6 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
}
}
BKE_pbvh_pmap_set(*ob->sculpt->pbvh, ob->sculpt->vert_to_face_map);
sculpt_attribute_update_refs(ob, BKE_pbvh_type(*ob->sculpt->pbvh));
return ob->sculpt->pbvh.get();
}

View File

@@ -1222,11 +1222,12 @@ static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
const Span<float3> positions = pbvh.vert_positions;
const OffsetIndices faces = mesh.faces();
const Span<int> corner_verts = mesh.corner_verts();
const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
VectorSet<int> boundary_faces;
for (const PBVHNode *node : nodes) {
for (const int vert : node->vert_indices.as_span().drop_front(node->uniq_verts)) {
boundary_faces.add_multiple(pbvh.vert_to_face_map[vert]);
boundary_faces.add_multiple(vert_to_face_map[vert]);
}
}
@@ -1257,15 +1258,14 @@ static void update_normals_faces(PBVH &pbvh, Span<PBVHNode *> nodes, Mesh &mesh)
});
if (pbvh.deformed) {
calc_node_vert_normals(
pbvh.vert_to_face_map, pbvh.face_normals, nodes, pbvh.vert_normals_deformed);
calc_node_vert_normals(vert_to_face_map, pbvh.face_normals, nodes, pbvh.vert_normals_deformed);
calc_boundary_vert_normals(
pbvh.vert_to_face_map, pbvh.face_normals, boundary_verts, pbvh.vert_normals_deformed);
vert_to_face_map, pbvh.face_normals, boundary_verts, pbvh.vert_normals_deformed);
}
else {
mesh.runtime->vert_normals_cache.update([&](Vector<float3> &r_data) {
calc_node_vert_normals(pbvh.vert_to_face_map, pbvh.face_normals, nodes, r_data);
calc_boundary_vert_normals(pbvh.vert_to_face_map, pbvh.face_normals, boundary_verts, r_data);
calc_node_vert_normals(vert_to_face_map, pbvh.face_normals, nodes, r_data);
calc_boundary_vert_normals(vert_to_face_map, pbvh.face_normals, boundary_verts, r_data);
});
pbvh.vert_normals = mesh.runtime->vert_normals_cache.data();
}
@@ -3065,11 +3065,6 @@ void BKE_pbvh_update_active_vcol(PBVH &pbvh, Mesh *mesh)
BKE_pbvh_get_color_layer(mesh, &pbvh.color_layer, &pbvh.color_domain);
}
void BKE_pbvh_pmap_set(PBVH &pbvh, const blender::GroupedSpan<int> vert_to_face_map)
{
pbvh.vert_to_face_map = vert_to_face_map;
}
void BKE_pbvh_ensure_node_loops(PBVH &pbvh)
{
using namespace blender;

View File

@@ -85,14 +85,17 @@ template<> void from_float(const float src[4], MPropCol &dst)
}
template<typename T>
static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_color[4])
static void pbvh_vertex_color_get(const PBVH &pbvh,
const blender::GroupedSpan<int> vert_to_face_map,
const PBVHVertRef vertex,
float r_color[4])
{
int index = vertex.i;
if (pbvh.color_domain == AttrDomain::Corner) {
int count = 0;
zero_v4(r_color);
for (const int i_face : pbvh.vert_to_face_map[index]) {
for (const int i_face : vert_to_face_map[index]) {
const IndexRange face = pbvh.faces[i_face];
Span<T> colors{static_cast<const T *>(pbvh.color_layer->data) + face.start(), face.size()};
Span<int> face_verts = pbvh.corner_verts.slice(face);
@@ -118,12 +121,15 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_
}
template<typename T>
static void pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float color[4])
static void pbvh_vertex_color_set(PBVH &pbvh,
const blender::GroupedSpan<int> vert_to_face_map,
const PBVHVertRef vertex,
const float color[4])
{
int index = vertex.i;
if (pbvh.color_domain == AttrDomain::Corner) {
for (const int i_face : pbvh.vert_to_face_map[index]) {
for (const int i_face : vert_to_face_map[index]) {
const IndexRange face = pbvh.faces[i_face];
MutableSpan<T> colors{static_cast<T *>(pbvh.color_layer->data) + face.start(), face.size()};
Span<int> face_verts = pbvh.corner_verts.slice(face);
@@ -142,23 +148,30 @@ static void pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float co
} // namespace blender::bke
void BKE_pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_color[4])
void BKE_pbvh_vertex_color_get(const PBVH &pbvh,
const blender::GroupedSpan<int> vert_to_face_map,
PBVHVertRef vertex,
float r_color[4])
{
blender::bke::to_static_color_type(eCustomDataType(pbvh.color_layer->type), [&](auto dummy) {
using T = decltype(dummy);
blender::bke::pbvh_vertex_color_get<T>(pbvh, vertex, r_color);
blender::bke::pbvh_vertex_color_get<T>(pbvh, vert_to_face_map, vertex, r_color);
});
}
void BKE_pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float color[4])
void BKE_pbvh_vertex_color_set(PBVH &pbvh,
const blender::GroupedSpan<int> vert_to_face_map,
const PBVHVertRef vertex,
const float color[4])
{
blender::bke::to_static_color_type(eCustomDataType(pbvh.color_layer->type), [&](auto dummy) {
using T = decltype(dummy);
blender::bke::pbvh_vertex_color_set<T>(pbvh, vertex, color);
blender::bke::pbvh_vertex_color_set<T>(pbvh, vert_to_face_map, vertex, color);
});
}
void BKE_pbvh_swap_colors(PBVH &pbvh,
const blender::GroupedSpan<int> vert_to_face_map,
const blender::Span<int> indices,
blender::MutableSpan<blender::float4> r_colors)
{
@@ -187,6 +200,7 @@ void BKE_pbvh_store_colors(PBVH &pbvh,
}
void BKE_pbvh_store_colors_vertex(PBVH &pbvh,
const blender::GroupedSpan<int> vert_to_face_map,
const blender::Span<int> indices,
blender::MutableSpan<blender::float4> r_colors)
{
@@ -197,7 +211,8 @@ void BKE_pbvh_store_colors_vertex(PBVH &pbvh,
blender::bke::to_static_color_type(eCustomDataType(pbvh.color_layer->type), [&](auto dummy) {
using T = decltype(dummy);
for (const int i : indices.index_range()) {
blender::bke::pbvh_vertex_color_get<T>(pbvh, BKE_pbvh_make_vref(indices[i]), r_colors[i]);
blender::bke::pbvh_vertex_color_get<T>(
pbvh, vert_to_face_map, BKE_pbvh_make_vref(indices[i]), r_colors[i]);
}
});
}

View File

@@ -179,8 +179,6 @@ struct PBVH {
BMLog *bm_log;
blender::GroupedSpan<int> vert_to_face_map;
CustomDataLayer *color_layer;
blender::bke::AttrDomain color_domain;

View File

@@ -223,12 +223,12 @@ bool SCULPT_has_colors(const SculptSession *ss)
void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4])
{
BKE_pbvh_vertex_color_get(*ss->pbvh, vertex, r_color);
BKE_pbvh_vertex_color_get(*ss->pbvh, ss->vert_to_face_map, vertex, r_color);
}
void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4])
{
BKE_pbvh_vertex_color_set(*ss->pbvh, vertex, color);
BKE_pbvh_vertex_color_set(*ss->pbvh, ss->vert_to_face_map, vertex, color);
}
void SCULPT_vertex_normal_get(const SculptSession *ss, PBVHVertRef vertex, float no[3])

View File

@@ -591,6 +591,7 @@ static bool restore_hidden_face(Object &object, Node &unode, MutableSpan<bool> m
static bool restore_color(Object &object, Node &unode, MutableSpan<bool> modified_vertices)
{
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
SculptSession *ss = object.sculpt;
bool modified = false;
@@ -598,15 +599,15 @@ static bool restore_color(Object &object, Node &unode, MutableSpan<bool> modifie
/* NOTE: even with loop colors we still store derived
* vertex colors for original data lookup. */
if (!unode.col.is_empty() && unode.loop_col.is_empty()) {
BKE_pbvh_swap_colors(
*ss->pbvh, unode.vert_indices.as_span().take_front(unode.unique_verts_num), unode.col);
BKE_pbvh_swap_colors(*ss->pbvh,
mesh.vert_to_face_map(),
unode.vert_indices.as_span().take_front(unode.unique_verts_num),
unode.col);
modified = true;
}
Mesh *mesh = BKE_object_get_original_mesh(&object);
if (!unode.loop_col.is_empty() && unode.mesh_corners_num == mesh->corners_num) {
BKE_pbvh_swap_colors(*ss->pbvh, unode.corner_indices, unode.loop_col);
if (!unode.loop_col.is_empty() && unode.mesh_corners_num == mesh.corners_num) {
BKE_pbvh_swap_colors(*ss->pbvh, mesh.vert_to_face_map(), unode.corner_indices, unode.loop_col);
modified = true;
}
@@ -1413,14 +1414,17 @@ static void store_mask(const Object &object, Node *unode)
static void store_color(const Object &object, Node *unode)
{
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
SculptSession *ss = object.sculpt;
BLI_assert(BKE_pbvh_type(*ss->pbvh) == PBVH_FACES);
/* NOTE: even with loop colors we still store (derived)
* vertex colors for original data lookup. */
BKE_pbvh_store_colors_vertex(
*ss->pbvh, unode->vert_indices.as_span().take_front(unode->unique_verts_num), unode->col);
BKE_pbvh_store_colors_vertex(*ss->pbvh,
mesh.vert_to_face_map(),
unode->vert_indices.as_span().take_front(unode->unique_verts_num),
unode->col);
if (!unode->loop_col.is_empty() && !unode->corner_indices.is_empty()) {
BKE_pbvh_store_colors(*ss->pbvh, unode->corner_indices, unode->loop_col);