Cleanup: Tweak PBVH grid faces update retrieval

The function really just gives an index mask of all the faces in the
provided nodes. The multires usage of the function didn't need that,
since it just passed all nodes. Also pass the SubdivCCG directly rather
than the PBVH. And rename the function to make this clearer.
This commit is contained in:
Hans Goudey
2023-12-18 15:06:45 -05:00
parent 25102af766
commit 8bf73a7a97
3 changed files with 18 additions and 21 deletions

View File

@@ -362,9 +362,11 @@ void update_normals(PBVH &pbvh, SubdivCCG *subdiv_ccg);
} // namespace blender::bke::pbvh
blender::Bounds<blender::float3> BKE_pbvh_redraw_BB(PBVH *pbvh);
blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
blender::Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory);
namespace blender::bke::pbvh {
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
Span<const PBVHNode *> nodes,
IndexMaskMemory &memory);
}
void BKE_pbvh_grids_update(PBVH *pbvh, const CCGKey *key);
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, SubdivCCG *subdiv_ccg);

View File

@@ -1202,6 +1202,7 @@ void multires_modifier_update_hidden(DerivedMesh *dm)
void multires_stitch_grids(Object *ob)
{
using namespace blender;
if (ob == nullptr) {
return;
}
@@ -1209,21 +1210,12 @@ void multires_stitch_grids(Object *ob)
if (sculpt_session == nullptr) {
return;
}
PBVH *pbvh = sculpt_session->pbvh;
SubdivCCG *subdiv_ccg = sculpt_session->subdiv_ccg;
if (pbvh == nullptr || subdiv_ccg == nullptr) {
if (subdiv_ccg == nullptr) {
return;
}
BLI_assert(BKE_pbvh_type(pbvh) == PBVH_GRIDS);
/* NOTE: Currently CCG does not keep track of faces, making it impossible
* to use BKE_pbvh_get_grid_updates().
*/
blender::IndexMaskMemory memory;
blender::Vector<PBVHNode *> nodes = blender::bke::pbvh::search_gather(pbvh, {});
const blender::IndexMask mask = BKE_pbvh_get_grid_updates(pbvh, nodes, memory);
if (!mask.is_empty()) {
BKE_subdiv_ccg_average_stitch_faces(*subdiv_ccg, mask);
}
BKE_subdiv_ccg_average_stitch_faces(*subdiv_ccg, IndexMask(subdiv_ccg->faces.size()));
}
DerivedMesh *multires_make_derived_from_derived(

View File

@@ -1258,7 +1258,7 @@ void update_normals(PBVH &pbvh, SubdivCCG *subdiv_ccg)
}
else if (pbvh.header.type == PBVH_GRIDS) {
IndexMaskMemory memory;
const IndexMask faces_to_update = BKE_pbvh_get_grid_updates(&pbvh, nodes, memory);
const IndexMask faces_to_update = nodes_to_face_selection_grids(*subdiv_ccg, nodes, memory);
BKE_subdiv_ccg_update_normals(*subdiv_ccg, faces_to_update);
for (PBVHNode *node : nodes) {
node->flag &= ~PBVH_UpdateNormals;
@@ -1586,16 +1586,17 @@ Bounds<float3> BKE_pbvh_redraw_BB(PBVH *pbvh)
return bounds;
}
blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
const Span<const PBVHNode *> nodes,
blender::IndexMaskMemory &memory)
namespace blender::bke::pbvh {
IndexMask nodes_to_face_selection_grids(const SubdivCCG &subdiv_ccg,
const Span<const PBVHNode *> nodes,
IndexMaskMemory &memory)
{
using namespace blender;
const Span<int> grid_to_face_map = pbvh->subdiv_ccg->grid_to_face_map;
const Span<int> grid_to_face_map = subdiv_ccg.grid_to_face_map;
/* Using a #VectorSet for index deduplication would also work, but the performance gets much
* worse with large selections since the loop would be single-threaded. A boolean array has an
* overhead regardless of selection size, but that is small. */
Array<bool> faces_to_update(pbvh->faces_num, false);
Array<bool> faces_to_update(subdiv_ccg.faces.size(), false);
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
for (const PBVHNode *node : nodes.slice(range)) {
for (const int grid : node->prim_indices) {
@@ -1606,6 +1607,8 @@ blender::IndexMask BKE_pbvh_get_grid_updates(const PBVH *pbvh,
return IndexMask::from_bools(faces_to_update, memory);
}
} // namespace blender::bke::pbvh
/***************************** PBVH Access ***********************************/
bool BKE_pbvh_get_color_layer(Mesh *mesh, CustomDataLayer **r_layer, eAttrDomain *r_domain)