From a7afc5b1e8dd2f38c26277b45ae487f736730f6d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 1 Dec 2023 14:37:49 -0500 Subject: [PATCH] Cleanup: Pass PBVH node grid indices as Span --- source/blender/blenkernel/BKE_pbvh_api.hh | 9 +- source/blender/blenkernel/intern/pbvh.cc | 91 +++-------- .../editors/sculpt_paint/paint_hide.cc | 18 +-- .../editors/sculpt_paint/sculpt_intern.hh | 1 - .../editors/sculpt_paint/sculpt_undo.cc | 145 ++++++++---------- 5 files changed, 94 insertions(+), 170 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh_api.hh b/source/blender/blenkernel/BKE_pbvh_api.hh index c544d3bd712..fb91a5a80fd 100644 --- a/source/blender/blenkernel/BKE_pbvh_api.hh +++ b/source/blender/blenkernel/BKE_pbvh_api.hh @@ -377,13 +377,8 @@ bool BKE_pbvh_node_fully_unmasked_get(PBVHNode *node); void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh); void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, PBVHVertRef vertex); -void BKE_pbvh_node_get_grids(PBVH *pbvh, - PBVHNode *node, - const int **grid_indices, - int *totgrid, - int *maxgrid, - int *gridsize, - CCGElem *const **r_griddata); +blender::Span BKE_pbvh_node_get_grid_indices(const PBVHNode &node); + void BKE_pbvh_node_num_verts(const PBVH *pbvh, const PBVHNode *node, int *r_uniquevert, diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index c79739ab7c1..857159e3026 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -1662,27 +1662,19 @@ static void pbvh_faces_node_visibility_update(const Mesh &mesh, const Span nodes) { using namespace blender; + CCGKey key = *BKE_pbvh_get_grid_key(pbvh); + const Span grid_hidden = pbvh->subdiv_ccg->grid_hidden; threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) { for (PBVHNode *node : nodes.slice(range)) { - CCGElem *const *grids; - const int *grid_indices; - int totgrid, i; - - BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids); - const Span grid_hidden = pbvh->subdiv_ccg->grid_hidden; - CCGKey key = *BKE_pbvh_get_grid_key(pbvh); - - for (i = 0; i < totgrid; i++) { - int g = grid_indices[i], x, y; - const BLI_bitmap *gh = grid_hidden[g]; - + for (const int grid_index : BKE_pbvh_node_get_grid_indices(*node)) { + const BLI_bitmap *gh = grid_hidden[grid_index]; if (!gh) { BKE_pbvh_node_fully_hidden_set(node, false); return; } - for (y = 0; y < key.grid_size; y++) { - for (x = 0; x < key.grid_size; x++) { + for (int y = 0; y < key.grid_size; y++) { + for (int x = 0; x < key.grid_size; x++) { if (!BLI_BITMAP_TEST(gh, y * key.grid_size + x)) { BKE_pbvh_node_fully_hidden_set(node, false); return; @@ -2054,51 +2046,9 @@ int BKE_pbvh_node_num_unique_verts(const PBVH &pbvh, const PBVHNode &node) return 0; } -void BKE_pbvh_node_get_grids(PBVH *pbvh, - PBVHNode *node, - const int **r_grid_indices, - int *r_totgrid, - int *r_maxgrid, - int *r_gridsize, - CCGElem *const **r_griddata) +Span BKE_pbvh_node_get_grid_indices(const PBVHNode &node) { - switch (pbvh->header.type) { - case PBVH_GRIDS: - if (r_grid_indices) { - *r_grid_indices = node->prim_indices.data(); - } - if (r_totgrid) { - *r_totgrid = node->prim_indices.size(); - } - if (r_maxgrid) { - *r_maxgrid = pbvh->subdiv_ccg->grids.size(); - } - if (r_gridsize) { - *r_gridsize = pbvh->gridkey.grid_size; - } - if (r_griddata) { - *r_griddata = pbvh->subdiv_ccg->grids.data(); - } - break; - case PBVH_FACES: - case PBVH_BMESH: - if (r_grid_indices) { - *r_grid_indices = nullptr; - } - if (r_totgrid) { - *r_totgrid = 0; - } - if (r_maxgrid) { - *r_maxgrid = 0; - } - if (r_gridsize) { - *r_gridsize = 0; - } - if (r_griddata) { - *r_griddata = nullptr; - } - break; - } + return node.prim_indices; } void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3]) @@ -3084,24 +3034,29 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh) void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode) { - CCGElem *const *grids; - const int *grid_indices; - int totgrid, gridsize, uniq_verts, totvert; - vi->grid = nullptr; vi->no = nullptr; vi->fno = nullptr; vi->vert_positions = {}; vi->vertex.i = 0LL; - BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, &gridsize, &grids); + int uniq_verts, totvert; BKE_pbvh_node_num_verts(pbvh, node, &uniq_verts, &totvert); - vi->key = pbvh->gridkey; - vi->grids = grids; - vi->grid_indices = grid_indices; - vi->totgrid = (grids) ? totgrid : 1; - vi->gridsize = gridsize; + if (pbvh->header.type == PBVH_GRIDS) { + vi->key = pbvh->gridkey; + vi->grids = pbvh->subdiv_ccg->grids.data(); + vi->grid_indices = node->prim_indices.data(); + vi->totgrid = node->prim_indices.size(); + vi->gridsize = pbvh->gridkey.grid_size; + } + else { + vi->key = {}; + vi->grids = nullptr; + vi->grid_indices = nullptr; + vi->totgrid = 1; + vi->gridsize = 0; + } if (mode == PBVH_ITER_ALL) { vi->totvert = totvert; diff --git a/source/blender/editors/sculpt_paint/paint_hide.cc b/source/blender/editors/sculpt_paint/paint_hide.cc index 8f5aa56e5ab..618a12caa47 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.cc +++ b/source/blender/editors/sculpt_paint/paint_hide.cc @@ -225,25 +225,19 @@ static void partialvis_update_grids(Depsgraph *depsgraph, const float planes[4][4], const Span nodes) { - SculptSession *ss = ob->sculpt; - SubdivCCG *subdiv_ccg = ss->subdiv_ccg; - MutableSpan grid_hidden = subdiv_ccg->grid_hidden; + SubdivCCG &subdiv_ccg = *ob->sculpt->subdiv_ccg; + const Span grids = subdiv_ccg.grids; const CCGKey key = *BKE_pbvh_get_grid_key(pbvh); + MutableSpan grid_hidden = subdiv_ccg.grid_hidden; for (PBVHNode *node : nodes) { - CCGElem *const *grids; - const int *grid_indices; - int totgrid; - bool any_changed = false, any_visible = false; - - /* Get PBVH data. */ - BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, &grids); + bool any_changed = false; + bool any_visible = false; SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); - for (int i = 0; i < totgrid; i++) { + for (const int grid_index : BKE_pbvh_node_get_grid_indices(*node)) { int any_hidden = 0; - const int grid_index = grid_indices[i]; BLI_bitmap *gh = grid_hidden[grid_index]; if (!gh) { switch (action) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index 39537b87b8e..399887683c8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -199,7 +199,6 @@ struct SculptUndoNode { /* multires */ int maxgrid; /* same for grid */ int gridsize; /* same for grid */ - int totgrid; /* to restore into right location */ blender::Array grids; /* to restore into right location */ BLI_bitmap **grid_hidden; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index c84a582cdcc..a10db0ea139 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -290,7 +290,7 @@ static void update_cb(PBVHNode *node, void *rebuild) struct PartialUpdateData { PBVH *pbvh; bool rebuild; - char *modified_grids; + bool *modified_grids; bool *modified_hidden_verts; bool *modified_mask_verts; bool *modified_color_verts; @@ -304,18 +304,12 @@ static void update_cb_partial(PBVHNode *node, void *userdata) { PartialUpdateData *data = static_cast(userdata); if (BKE_pbvh_type(data->pbvh) == PBVH_GRIDS) { - const int *node_grid_indices; - int totgrid; - bool update = false; - BKE_pbvh_node_get_grids( - data->pbvh, node, &node_grid_indices, &totgrid, nullptr, nullptr, nullptr); - for (int i = 0; i < totgrid; i++) { - if (data->modified_grids[node_grid_indices[i]] == 1) { - update = true; - } - } - if (update) { - update_cb(node, &(data->rebuild)); + const Span grid_indices = BKE_pbvh_node_get_grid_indices(*node); + if (std::any_of(grid_indices.begin(), grid_indices.end(), [&](const int grid) { + return data->modified_grids[grid]; + })) + { + update_cb(node, &data->rebuild); } } else { @@ -383,6 +377,7 @@ static bool sculpt_undo_restore_deformed( static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, SculptUndoNode *unode) { + using namespace blender; const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); BKE_view_layer_synced_ensure(scene, view_layer); @@ -467,23 +462,20 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt } } } - else if (unode->maxgrid && subdiv_ccg != nullptr) { - /* Multires restore. */ - CCGElem **grids, *grid; + else if (!unode->grids.is_empty() && subdiv_ccg != nullptr) { + const int gridsize = subdiv_ccg->grid_size; CCGKey key; - int gridsize; - - grids = subdiv_ccg->grids.data(); - gridsize = subdiv_ccg->grid_size; BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg); + const Span grid_indices = unode->grids; blender::MutableSpan co = unode->co; - int index = 0; - for (int j = 0; j < unode->totgrid; j++) { - grid = grids[unode->grids[j]]; + MutableSpan grids = subdiv_ccg->grids; - for (int i = 0; i < gridsize * gridsize; i++) { - swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[index]); + int index = 0; + for (const int i : grid_indices.index_range()) { + CCGElem *grid = grids[grid_indices[i]]; + for (const int j : IndexRange(gridsize * gridsize)) { + swap_v3_v3(CCG_elem_offset_co(&key, grid, j), co[index]); index++; } } @@ -517,11 +509,11 @@ static bool sculpt_undo_restore_hidden(bContext *C, SculptUndoNode *unode, bool } hide_vert.finish(); } - else if (unode->maxgrid && subdiv_ccg != nullptr) { + else if (!unode->grids.is_empty() && subdiv_ccg != nullptr) { + const Span grids = unode->grids; blender::MutableSpan grid_hidden = subdiv_ccg->grid_hidden; - - for (int i = 0; i < unode->totgrid; i++) { - SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]); + for (const int i : grids.index_range()) { + SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[grids[i]]); } } @@ -589,23 +581,22 @@ static bool sculpt_undo_restore_mask(bContext *C, SculptUndoNode *unode, bool *m mask.finish(); } - else if (unode->maxgrid && subdiv_ccg != nullptr) { - /* Multires restore. */ - CCGElem **grids, *grid; + else if (!unode->grids.is_empty() && subdiv_ccg != nullptr) { + const int gridsize = subdiv_ccg->grid_size; CCGKey key; - int gridsize; + BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg); + const Span grid_indices = unode->grids; - grids = subdiv_ccg->grids.data(); - gridsize = subdiv_ccg->grid_size; BKE_subdiv_ccg_key_top_level(key, *subdiv_ccg); blender::MutableSpan mask = unode->mask; - int index = 0; - for (int j = 0; j < unode->totgrid; j++) { - grid = grids[unode->grids[j]]; + MutableSpan grids = subdiv_ccg->grids; - for (int i = 0; i < gridsize * gridsize; i++) { - std::swap(*CCG_elem_offset_mask(&key, grid, i), mask[index]); + int index = 0; + for (const int i : grid_indices.index_range()) { + CCGElem *grid = grids[grid_indices[i]]; + for (const int j : IndexRange(gridsize * gridsize)) { + std::swap(*CCG_elem_offset_mask(&key, grid, j), mask[index]); index++; } } @@ -917,7 +908,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase bool *modified_mask_verts = nullptr; bool *modified_color_verts = nullptr; bool *modified_face_set_faces = nullptr; - char *undo_modified_grids = nullptr; + bool *undo_modified_grids = nullptr; bool use_multires_undo = false; LISTBASE_FOREACH (SculptUndoNode *, unode, lb) { @@ -1012,12 +1003,12 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } if (undo_modified_grids == nullptr) { - undo_modified_grids = static_cast( - MEM_callocN(sizeof(char) * unode->maxgrid, "undo_grids")); + undo_modified_grids = static_cast( + MEM_callocN(sizeof(bool) * unode->maxgrid, "undo_grids")); } - for (int i = 0; i < unode->totgrid; i++) { - undo_modified_grids[unode->grids[i]] = 1; + for (const int grid : unode->grids) { + undo_modified_grids[grid] = true; } } } @@ -1097,10 +1088,8 @@ static void sculpt_undo_free_list(ListBase *lb) SculptUndoNode *unode_next = unode->next; if (unode->grid_hidden) { - for (int i = 0; i < unode->totgrid; i++) { - if (unode->grid_hidden[i]) { - MEM_freeN(unode->grid_hidden[i]); - } + for (const int i : unode->grids.index_range()) { + MEM_SAFE_FREE(unode->grid_hidden[i]); } MEM_freeN(unode->grid_hidden); } @@ -1172,21 +1161,18 @@ SculptUndoNode *SCULPT_undo_get_first_node() static size_t sculpt_undo_alloc_and_store_hidden(SculptSession *ss, SculptUndoNode *unode) { - PBVH *pbvh = ss->pbvh; PBVHNode *node = static_cast(unode->node); const blender::Span grid_hidden = ss->subdiv_ccg->grid_hidden; - const int *grid_indices; - int totgrid; - BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, nullptr, nullptr, nullptr); + const Span grid_indices = BKE_pbvh_node_get_grid_indices(*node); - size_t alloc_size = sizeof(*unode->grid_hidden) * size_t(totgrid); + size_t alloc_size = sizeof(*unode->grid_hidden) * grid_indices.size(); unode->grid_hidden = static_cast(MEM_callocN(alloc_size, "unode->grid_hidden")); - for (int i = 0; i < totgrid; i++) { - if (grid_hidden[grid_indices[i]]) { - unode->grid_hidden[i] = static_cast( - MEM_dupallocN(grid_hidden[grid_indices[i]])); + for (const int i : grid_indices.index_range()) { + const int grid_index = grid_indices[i]; + if (grid_hidden[grid_index]) { + unode->grid_hidden[i] = static_cast(MEM_dupallocN(grid_hidden[grid_index])); alloc_size += MEM_allocN_len(unode->grid_hidden[i]); } else { @@ -1233,23 +1219,21 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt { UndoSculpt *usculpt = sculpt_undo_get_nodes(); SculptSession *ss = ob->sculpt; - int totvert = 0; - int allvert = 0; - int totgrid = 0; - int maxgrid = 0; - int gridsize = 0; - const int *grids = nullptr; SculptUndoNode *unode = sculpt_undo_alloc_node_type(ob, type); unode->node = node; - if (node) { - BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert); - BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, &maxgrid, &gridsize, nullptr); + int totvert = 0; + int allvert = 0; + BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert); - unode->totvert = totvert; + Span grids; + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + grids = BKE_pbvh_node_get_grid_indices(*node); } + unode->totvert = totvert; + bool need_loops = type == SCULPT_UNDO_COLOR; const bool need_faces = type == SCULPT_UNDO_FACE_SETS; @@ -1281,13 +1265,13 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt break; } case SCULPT_UNDO_HIDDEN: { - if (maxgrid) { - usculpt->undo_size += sculpt_undo_alloc_and_store_hidden(ss, unode); - } - else { + if (grids.is_empty()) { unode->vert_hidden.resize(allvert); usculpt->undo_size += BLI_BITMAP_SIZE(allvert); } + else { + usculpt->undo_size += sculpt_undo_alloc_and_store_hidden(ss, unode); + } break; } @@ -1323,13 +1307,12 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt } } - if (maxgrid) { + if (!grids.is_empty()) { /* Multires. */ - unode->maxgrid = maxgrid; - unode->totgrid = totgrid; - unode->gridsize = gridsize; + unode->maxgrid = ss->subdiv_ccg->grids.size(); + unode->gridsize = ss->subdiv_ccg->grid_size; - unode->grids.reinitialize(totgrid); + unode->grids.reinitialize(grids.size()); usculpt->undo_size += unode->grids.as_span().size_in_bytes(); } else { @@ -1556,10 +1539,7 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType */ if (!unode->grids.is_empty()) { - int totgrid; - const int *grids; - BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid, nullptr, nullptr, nullptr); - unode->grids.as_mutable_span().copy_from({grids, totgrid}); + unode->grids.as_mutable_span().copy_from(BKE_pbvh_node_get_grid_indices(*node)); } else { unode->index.as_mutable_span().copy_from(BKE_pbvh_node_get_vert_indices(node)); @@ -2038,7 +2018,8 @@ static void sculpt_undo_push_all_grids(Object *object) * to the current operation without making any stroke in between. * * Skip pushing nodes based on the following logic: on redo SCULPT_UNDO_COORDS will ensure - * PBVH for the new base geometry, which will have same coordinates as if we create PBVH here. */ + * PBVH for the new base geometry, which will have same coordinates as if we create PBVH here. + */ if (ss->pbvh == nullptr) { return; }