From 1be70f22ccb7ea1e75d600bf7083da9358fce06d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 27 Jul 2023 16:21:34 -0400 Subject: [PATCH] Cleanup: Use C++ containers and spans for some PBVH data One thing to point out is that `PBVH::nodes` is now stored in a `Vector` which replaces the manual amortized growth. That requires explicitly setting the defaults of PBVHNode fields for default initialization. Similar to f0b53777c8b94143bd0dac0dfc15edfaeb24ed8a --- source/blender/blenkernel/BKE_pbvh_api.hh | 10 +- source/blender/blenkernel/intern/pbvh.cc | 378 +++++++----------- .../blender/blenkernel/intern/pbvh_bmesh.cc | 68 ++-- .../blender/blenkernel/intern/pbvh_colors.cc | 4 +- .../blender/blenkernel/intern/pbvh_intern.hh | 63 +-- .../blender/blenkernel/intern/pbvh_pixels.cc | 46 +-- .../blenkernel/intern/pbvh_pixels_copy.cc | 4 +- source/blender/draw/DRW_pbvh.hh | 9 +- source/blender/draw/intern/draw_pbvh.cc | 31 +- 9 files changed, 255 insertions(+), 358 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh_api.hh b/source/blender/blenkernel/BKE_pbvh_api.hh index 851a7ff841e..7628f541d98 100644 --- a/source/blender/blenkernel/BKE_pbvh_api.hh +++ b/source/blender/blenkernel/BKE_pbvh_api.hh @@ -65,7 +65,7 @@ struct PBVHProxyNode { }; struct PBVHColorBufferNode { - float (*color)[4]; + float (*color)[4] = nullptr; }; struct PBVHPixels { @@ -83,7 +83,7 @@ struct PBVHPixelsNode { * * Contains #blender::bke::pbvh::pixels::NodeData. */ - void *node_data; + void *node_data = nullptr; }; struct PBVHAttrReq { @@ -617,9 +617,9 @@ struct PBVHFaceIter { int cd_hide_poly_, cd_face_set_; bool *hide_poly_; int *face_sets_; - const int *face_offsets_; - const int *looptri_faces_; - const int *corner_verts_; + blender::OffsetIndices face_offsets_; + blender::Span looptri_faces_; + blender::Span corner_verts_; int prim_index_; const SubdivCCG *subdiv_ccg_; const BMesh *bm; diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index b324d417574..c4e2dd5483b 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -187,14 +187,14 @@ static bool grid_materials_match(const DMFlagMat *f1, const DMFlagMat *f2) /* Adapted from BLI_kdopbvh.c */ /* Returns the index of the first element on the right of the partition */ -static int partition_indices_faces(int *prim_indices, +static int partition_indices_faces(blender::MutableSpan prim_indices, int *prim_scratch, int lo, int hi, int axis, float mid, - BBC *prim_bbc, - const int *looptri_faces) + const Span prim_bbc, + const Span looptri_faces) { for (int i = lo; i < hi; i++) { prim_scratch[i - lo] = prim_indices[i]; @@ -217,13 +217,13 @@ static int partition_indices_faces(int *prim_indices, return lo2; } -static int partition_indices_grids(int *prim_indices, +static int partition_indices_grids(blender::MutableSpan prim_indices, int *prim_scratch, int lo, int hi, int axis, float mid, - BBC *prim_bbc, + const Span prim_bbc, SubdivCCG *subdiv_ccg) { for (int i = lo; i < hi; i++) { @@ -251,13 +251,13 @@ static int partition_indices_grids(int *prim_indices, static int partition_indices_material( PBVH *pbvh, const int *material_indices, const bool *sharp_faces, int lo, int hi) { - const int *looptri_faces = pbvh->looptri_faces; + const Span looptri_faces = pbvh->looptri_faces; const DMFlagMat *flagmats = pbvh->grid_flag_mats; - const int *indices = pbvh->prim_indices; + MutableSpan indices = pbvh->prim_indices; int i = lo, j = hi; for (;;) { - if (pbvh->looptri_faces) { + if (!pbvh->looptri_faces.is_empty()) { const int first = looptri_faces[pbvh->prim_indices[lo]]; for (; face_materials_match(material_indices, sharp_faces, first, looptri_faces[indices[i]]); i++) { @@ -283,28 +283,19 @@ static int partition_indices_material( return i; } - SWAP(int, pbvh->prim_indices[i], pbvh->prim_indices[j]); + std::swap(pbvh->prim_indices[i], pbvh->prim_indices[j]); i++; } } void pbvh_grow_nodes(PBVH *pbvh, int totnode) { - if (UNLIKELY(totnode > pbvh->node_mem_count)) { - pbvh->node_mem_count = pbvh->node_mem_count + (pbvh->node_mem_count / 3); - if (pbvh->node_mem_count < totnode) { - pbvh->node_mem_count = totnode; - } - pbvh->nodes = static_cast( - MEM_recallocN(pbvh->nodes, sizeof(PBVHNode) * pbvh->node_mem_count)); - } - - pbvh->totnode = totnode; + pbvh->nodes.resize(totnode); } /* Add a vertex to the map, with a positive value for unique vertices and * a negative value for additional vertices */ -static int map_insert_vert(PBVH *pbvh, GHash *map, uint *face_verts, uint *uniq_verts, int vertex) +static int map_insert_vert(PBVH *pbvh, GHash *map, int *face_verts, int *uniq_verts, int vertex) { void *key, **value_p; @@ -333,33 +324,29 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) bool has_visible = false; node->uniq_verts = node->face_verts = 0; - const int totface = node->totprim; + const int totface = node->prim_indices.size(); /* reserve size is rough guess */ GHash *map = BLI_ghash_int_new_ex("build_mesh_leaf_node gh", 2 * totface); - int(*face_vert_indices)[3] = static_cast( - MEM_mallocN(sizeof(int[3]) * totface, __func__)); - - node->face_vert_indices = (const int(*)[3])face_vert_indices; + node->face_vert_indices.reinitialize(totface); for (int i = 0; i < totface; i++) { const MLoopTri *lt = &pbvh->looptri[node->prim_indices[i]]; for (int j = 0; j < 3; j++) { - face_vert_indices[i][j] = map_insert_vert( + node->face_vert_indices[i][j] = map_insert_vert( pbvh, map, &node->face_verts, &node->uniq_verts, pbvh->corner_verts[lt->tri[j]]); } if (has_visible == false) { - if (!paint_is_face_hidden(pbvh->looptri_faces, pbvh->hide_poly, node->prim_indices[i])) { + if (!paint_is_face_hidden( + pbvh->looptri_faces.data(), pbvh->hide_poly, node->prim_indices[i])) { has_visible = true; } } } - int *vert_indices = static_cast( - MEM_callocN(sizeof(int) * (node->uniq_verts + node->face_verts), __func__)); - node->vert_indices = vert_indices; + node->vert_indices.reinitialize(node->uniq_verts + node->face_verts); /* Build the vertex list, unique verts first */ GHashIterator gh_iter; @@ -371,15 +358,15 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) ndx = -ndx + node->uniq_verts - 1; } - vert_indices[ndx] = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter)); + node->vert_indices[ndx] = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter)); } for (int i = 0; i < totface; i++) { const int sides = 3; for (int j = 0; j < sides; j++) { - if (face_vert_indices[i][j] < 0) { - face_vert_indices[i][j] = -face_vert_indices[i][j] + node->uniq_verts - 1; + if (node->face_vert_indices[i][j] < 0) { + node->face_vert_indices[i][j] = -node->face_vert_indices[i][j] + node->uniq_verts - 1; } } } @@ -391,7 +378,7 @@ static void build_mesh_leaf_node(PBVH *pbvh, PBVHNode *node) BLI_ghash_free(map, nullptr, nullptr); } -static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int count) +static void update_vb(PBVH *pbvh, PBVHNode *node, const Span prim_bbc, int offset, int count) { BB_reset(&node->vb); for (int i = offset + count - 1; i >= offset; i--) { @@ -441,29 +428,28 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node) { int totquads = BKE_pbvh_count_grid_quads(pbvh->grid_hidden, - node->prim_indices, - node->totprim, + node->prim_indices.data(), + node->prim_indices.size(), pbvh->gridkey.grid_size, pbvh->gridkey.grid_size); BKE_pbvh_node_fully_hidden_set(node, (totquads == 0)); BKE_pbvh_node_mark_rebuild_draw(node); } -static void build_leaf(PBVH *pbvh, int node_index, BBC *prim_bbc, int offset, int count) +static void build_leaf(PBVH *pbvh, int node_index, const Span prim_bbc, int offset, int count) { pbvh->nodes[node_index].flag |= PBVH_Leaf; - pbvh->nodes[node_index].prim_indices = pbvh->prim_indices + offset; - pbvh->nodes[node_index].totprim = count; + pbvh->nodes[node_index].prim_indices = pbvh->prim_indices.as_span().slice(offset, count); /* Still need vb for searches */ update_vb(pbvh, &pbvh->nodes[node_index], prim_bbc, offset, count); - if (pbvh->looptri) { - build_mesh_leaf_node(pbvh, pbvh->nodes + node_index); + if (!pbvh->looptri.is_empty()) { + build_mesh_leaf_node(pbvh, &pbvh->nodes[node_index]); } else { - build_grid_leaf_node(pbvh, pbvh->nodes + node_index); + build_grid_leaf_node(pbvh, &pbvh->nodes[node_index]); } } @@ -476,7 +462,7 @@ static bool leaf_needs_material_split( return false; } - if (pbvh->looptri) { + if (!pbvh->looptri.is_empty()) { const int first = pbvh->looptri_faces[pbvh->prim_indices[offset]]; for (int i = offset + count - 1; i > offset; i--) { int prim = pbvh->prim_indices[i]; @@ -563,7 +549,7 @@ static void build_sub(PBVH *pbvh, const bool *sharp_faces, int node_index, BB *cb, - BBC *prim_bbc, + const Span prim_bbc, int offset, int count, int *prim_scratch, @@ -591,8 +577,8 @@ static void build_sub(PBVH *pbvh, } /* Add two child nodes */ - pbvh->nodes[node_index].children_offset = pbvh->totnode; - pbvh_grow_nodes(pbvh, pbvh->totnode + 2); + pbvh->nodes[node_index].children_offset = pbvh->nodes.size(); + pbvh_grow_nodes(pbvh, pbvh->nodes.size() + 2); /* Update parent node bounding box */ update_vb(pbvh, &pbvh->nodes[node_index], prim_bbc, offset, count); @@ -667,30 +653,19 @@ static void pbvh_build(PBVH *pbvh, const int *material_indices, const bool *sharp_faces, BB *cb, - BBC *prim_bbc, + const Span prim_bbc, int totprim) { if (totprim != pbvh->totprim) { pbvh->totprim = totprim; - if (pbvh->nodes) { - MEM_freeN(pbvh->nodes); - } - if (pbvh->prim_indices) { - MEM_freeN(pbvh->prim_indices); - } - pbvh->prim_indices = static_cast(MEM_mallocN(sizeof(int) * totprim, __func__)); - for (int i = 0; i < totprim; i++) { - pbvh->prim_indices[i] = i; - } - pbvh->totnode = 0; - if (pbvh->node_mem_count < 100) { - pbvh->node_mem_count = 100; - pbvh->nodes = static_cast( - MEM_callocN(sizeof(PBVHNode) * pbvh->node_mem_count, __func__)); - } + pbvh->nodes.clear_and_shrink(); + + pbvh->prim_indices.reinitialize(totprim); + std::iota(pbvh->prim_indices.begin(), pbvh->prim_indices.end(), 0); } - pbvh->totnode = 1; + pbvh->nodes.resize(1); + build_sub(pbvh, material_indices, sharp_faces, 0, cb, prim_bbc, 0, totprim, nullptr, 0); } @@ -707,7 +682,7 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->face_sets_color_seed = pbvh->face_sets_color_seed; args->vert_positions = pbvh->vert_positions; if (pbvh->mesh) { - args->corner_verts = {pbvh->corner_verts, pbvh->mesh->totloop}; + args->corner_verts = pbvh->corner_verts; args->corner_edges = pbvh->mesh->corner_edges(); } args->faces = pbvh->faces; @@ -724,7 +699,6 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->vert_data = pbvh->vert_data; args->loop_data = pbvh->loop_data; args->face_data = pbvh->face_data; - args->totprim = node->totprim; args->me = pbvh->mesh; args->faces = pbvh->faces; args->vert_normals = pbvh->vert_normals; @@ -742,7 +716,6 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->face_data = pbvh->face_data; args->ccg_key = pbvh->gridkey; args->me = pbvh->mesh; - args->totprim = node->totprim; args->grid_indices = node->prim_indices; args->subdiv_ccg = pbvh->subdiv_ccg; args->face_sets = pbvh->face_sets; @@ -768,7 +741,6 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->bm_faces = node->bm_faces; args->bm_other_verts = node->bm_other_verts; args->bm_unique_vert = node->bm_unique_verts; - args->totprim = BLI_gset_len(node->bm_faces); args->cd_mask_layer = CustomData_get_offset(&pbvh->header.bm->vdata, CD_PAINT_MASK); break; @@ -847,8 +819,8 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh) BLI_assert(pbvh->header.type == PBVH_FACES); pbvh->faces = mesh->faces(); - pbvh->corner_verts = mesh->corner_verts().data(); - pbvh->looptri_faces = mesh->looptri_faces().data(); + pbvh->corner_verts = mesh->corner_verts(); + pbvh->looptri_faces = mesh->looptri_faces(); if (!pbvh->deformed) { /* Deformed positions not matching the original mesh are owned directly by the PBVH, and are @@ -875,7 +847,6 @@ void BKE_pbvh_update_mesh_pointers(PBVH *pbvh, Mesh *mesh) void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) { - BBC *prim_bbc = nullptr; BB cb; const int totvert = mesh->totvert; @@ -884,10 +855,9 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) const blender::OffsetIndices faces = mesh->faces(); const Span corner_verts = mesh->corner_verts(); - MLoopTri *looptri = static_cast( - MEM_malloc_arrayN(looptri_num, sizeof(*looptri), __func__)); + pbvh->looptri.reinitialize(looptri_num); - blender::bke::mesh::looptris_calc(vert_positions, faces, corner_verts, {looptri, looptri_num}); + blender::bke::mesh::looptris_calc(vert_positions, faces, corner_verts, pbvh->looptri); pbvh->mesh = mesh; pbvh->header.type = PBVH_FACES; @@ -895,9 +865,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) BKE_pbvh_update_mesh_pointers(pbvh, mesh); /* Those are not set in #BKE_pbvh_update_mesh_pointers because they are owned by the #PBVH. */ - pbvh->looptri = looptri; - pbvh->vert_bitmap = static_cast( - MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap")); + pbvh->vert_bitmap = blender::Array(totvert, false); pbvh->totvert = totvert; #ifdef TEST_PBVH_FACE_SPLIT @@ -917,12 +885,12 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) BB_reset(&cb); /* For each face, store the AABB and the AABB centroid */ - prim_bbc = static_cast(MEM_mallocN(sizeof(BBC) * looptri_num, __func__)); + blender::Array prim_bbc(looptri_num); for (int i = 0; i < looptri_num; i++) { - const MLoopTri *lt = &looptri[i]; + const MLoopTri *lt = &pbvh->looptri[i]; const int sides = 3; - BBC *bbc = prim_bbc + i; + BBC *bbc = &prim_bbc[i]; BB_reset((BB *)bbc); @@ -947,10 +915,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh) #endif } - MEM_freeN(prim_bbc); - /* Clear the bitmap so it can be used as an update tag later on. */ - memset(pbvh->vert_bitmap, 0, sizeof(bool) * totvert); + pbvh->vert_bitmap.fill(false); BKE_pbvh_update_active_vcol(pbvh, mesh); @@ -1000,7 +966,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh, pbvh->face_data = &me->face_data; pbvh->faces = faces; - pbvh->corner_verts = me->corner_verts().data(); + pbvh->corner_verts = me->corner_verts(); /* We also need the base mesh for PBVH draw. */ pbvh->mesh = me; @@ -1009,11 +975,11 @@ void BKE_pbvh_build_grids(PBVH *pbvh, BB_reset(&cb); /* For each grid, store the AABB and the AABB centroid */ - BBC *prim_bbc = static_cast(MEM_mallocN(sizeof(BBC) * totgrid, __func__)); + blender::Array prim_bbc(totgrid); for (int i = 0; i < totgrid; i++) { CCGElem *grid = grids[i]; - BBC *bbc = prim_bbc + i; + BBC *bbc = &prim_bbc[i]; BB_reset((BB *)bbc); @@ -1038,7 +1004,6 @@ void BKE_pbvh_build_grids(PBVH *pbvh, #endif } - MEM_freeN(prim_bbc); #ifdef VALIDATE_UNIQUE_NODE_FACES pbvh_validate_node_prims(pbvh); #endif @@ -1059,52 +1024,28 @@ PBVH *BKE_pbvh_new(PBVHType type) void BKE_pbvh_free(PBVH *pbvh) { - for (int i = 0; i < pbvh->totnode; i++) { - PBVHNode *node = &pbvh->nodes[i]; + for (PBVHNode &node : pbvh->nodes) { + if (node.flag & PBVH_Leaf) { + if (node.draw_batches) { + DRW_pbvh_node_free(node.draw_batches); + } - if (node->flag & PBVH_Leaf) { - if (node->draw_batches) { - DRW_pbvh_node_free(node->draw_batches); + if (node.bm_faces) { + BLI_gset_free(node.bm_faces, nullptr); } - if (node->vert_indices) { - MEM_freeN((void *)node->vert_indices); + if (node.bm_unique_verts) { + BLI_gset_free(node.bm_unique_verts, nullptr); } - if (node->loop_indices) { - MEM_freeN(node->loop_indices); - } - if (node->face_vert_indices) { - MEM_freeN((void *)node->face_vert_indices); - } - if (node->bm_faces) { - BLI_gset_free(node->bm_faces, nullptr); - } - if (node->bm_unique_verts) { - BLI_gset_free(node->bm_unique_verts, nullptr); - } - if (node->bm_other_verts) { - BLI_gset_free(node->bm_other_verts, nullptr); + if (node.bm_other_verts) { + BLI_gset_free(node.bm_other_verts, nullptr); } } - if (node->flag & (PBVH_Leaf | PBVH_TexLeaf)) { - pbvh_node_pixels_free(node); + if (node.flag & (PBVH_Leaf | PBVH_TexLeaf)) { + pbvh_node_pixels_free(&node); } } - if (pbvh->looptri) { - MEM_freeN((void *)pbvh->looptri); - } - - if (pbvh->nodes) { - MEM_freeN(pbvh->nodes); - } - - if (pbvh->prim_indices) { - MEM_freeN(pbvh->prim_indices); - } - - MEM_SAFE_FREE(pbvh->vert_bitmap); - pbvh_pixels_free(pbvh); MEM_delete(pbvh); @@ -1122,7 +1063,7 @@ static void pbvh_iter_begin(PBVHIter *iter, iter->stack = iter->stackfixed; iter->stackspace = STACK_FIXED_DEPTH; - iter->stack[0].node = pbvh->nodes; + iter->stack[0].node = &pbvh->nodes.first(); iter->stack[0].revisiting = false; iter->stacksize = 1; } @@ -1190,8 +1131,8 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag) pbvh_stack_push(iter, node, true); /* push two child nodes on the stack */ - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false); - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false); + pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset + 1], false); + pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset], false); } return nullptr; @@ -1219,8 +1160,8 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter) return node; } - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false); - pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false); + pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset + 1], false); + pbvh_stack_push(iter, &iter->pbvh->nodes[node->children_offset], false); } return nullptr; @@ -1377,13 +1318,13 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span nodes) using namespace blender::bke; const Span positions = pbvh->vert_positions; const OffsetIndices faces = pbvh->faces; - const Span corner_verts(pbvh->corner_verts, pbvh->mesh->totloop); + const Span corner_verts = pbvh->corner_verts; - MutableSpan update_tags(pbvh->vert_bitmap, pbvh->totvert); + MutableSpan update_tags = pbvh->vert_bitmap; VectorSet faces_to_update; for (const PBVHNode *node : nodes) { - for (const int vert : Span(node->vert_indices, node->uniq_verts)) { + for (const int vert : node->vert_indices.as_span().take_front(node->uniq_verts)) { if (update_tags[vert]) { faces_to_update.add_multiple(pbvh->pmap[vert]); } @@ -1674,8 +1615,8 @@ static int pbvh_flush_bb(PBVH *pbvh, PBVHNode *node, int flag) return update; } - update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset, flag); - update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset + 1, flag); + update |= pbvh_flush_bb(pbvh, &pbvh->nodes[node->children_offset], flag); + update |= pbvh_flush_bb(pbvh, &pbvh->nodes[node->children_offset + 1], flag); if (update & PBVH_UpdateBB) { update_node_vb(pbvh, node); @@ -1689,7 +1630,7 @@ static int pbvh_flush_bb(PBVH *pbvh, PBVHNode *node, int flag) void BKE_pbvh_update_bounds(PBVH *pbvh, int flag) { - if (!pbvh->nodes) { + if (pbvh->nodes.is_empty()) { return; } @@ -1701,13 +1642,13 @@ void BKE_pbvh_update_bounds(PBVH *pbvh, int flag) } if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB)) { - pbvh_flush_bb(pbvh, pbvh->nodes, flag); + pbvh_flush_bb(pbvh, &pbvh->nodes.first(), flag); } } void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag) { - if (!pbvh->nodes) { + if (pbvh->nodes.is_empty()) { return; } @@ -1845,7 +1786,7 @@ static void pbvh_update_visibility(PBVH *pbvh, Span nodes) void BKE_pbvh_update_visibility(PBVH *pbvh) { - if (!pbvh->nodes) { + if (pbvh->nodes.is_empty()) { return; } @@ -1887,8 +1828,8 @@ void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) { if (node->flag & PBVH_UpdateNormals) { - for (uint i = 0; i < node->totprim; i++) { - void *face = pbvh->gridfaces[node->prim_indices[i]]; + for (const int grid : node->prim_indices) { + void *face = pbvh->gridfaces[grid]; BLI_gset_add(face_set, face); } @@ -1935,15 +1876,14 @@ bool BKE_pbvh_has_faces(const PBVH *pbvh) void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3]) { - if (pbvh->totnode) { - const BB *bb = &pbvh->nodes[0].vb; - copy_v3_v3(min, bb->bmin); - copy_v3_v3(max, bb->bmax); - } - else { + if (pbvh->nodes.is_empty()) { zero_v3(min); zero_v3(max); + return; } + const BB *bb = &pbvh->nodes[0].vb; + copy_v3_v3(min, bb->bmin); + copy_v3_v3(max, bb->bmax); } BLI_bitmap **BKE_pbvh_grid_hidden(const PBVH *pbvh) @@ -2007,10 +1947,9 @@ void BKE_pbvh_node_mark_update_face_sets(PBVHNode *node) void BKE_pbvh_mark_rebuild_pixels(PBVH *pbvh) { - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - if (node->flag & PBVH_Leaf) { - node->flag |= PBVH_RebuildPixels; + for (PBVHNode &node : pbvh->nodes) { + if (node.flag & PBVH_Leaf) { + node.flag |= PBVH_RebuildPixels; } } } @@ -2101,11 +2040,11 @@ void BKE_pbvh_node_get_loops(PBVH *pbvh, BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); if (r_loop_indices) { - *r_loop_indices = node->loop_indices; + *r_loop_indices = node->loop_indices.data(); } if (r_corner_verts) { - *r_corner_verts = pbvh->corner_verts; + *r_corner_verts = pbvh->corner_verts.data(); } } @@ -2124,9 +2063,8 @@ int BKE_pbvh_num_faces(const PBVH *pbvh) } const int *BKE_pbvh_node_get_vert_indices(PBVHNode *node) - { - return node->vert_indices; + return node->vert_indices.data(); } void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert) @@ -2135,7 +2073,7 @@ void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int switch (pbvh->header.type) { case PBVH_GRIDS: - tot = node->totprim * pbvh->gridkey.grid_area; + tot = node->prim_indices.size() * pbvh->gridkey.grid_area; if (r_totvert) { *r_totvert = tot; } @@ -2174,10 +2112,10 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh, switch (pbvh->header.type) { case PBVH_GRIDS: if (r_grid_indices) { - *r_grid_indices = node->prim_indices; + *r_grid_indices = node->prim_indices.data(); } if (r_totgrid) { - *r_totgrid = node->totprim; + *r_totgrid = node->prim_indices.size(); } if (r_maxgrid) { *r_maxgrid = pbvh->totgrid; @@ -2260,17 +2198,11 @@ void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node, bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node) { BLI_assert(pbvh->header.type == PBVH_FACES); - const int *verts = node->vert_indices; - const int totvert = node->uniq_verts + node->face_verts; - - for (int i = 0; i < totvert; i++) { - const int v = verts[i]; - - if (pbvh->vert_bitmap[v]) { + for (const int vert : node->vert_indices) { + if (pbvh->vert_bitmap[vert]) { return true; } } - return false; } @@ -2443,18 +2375,16 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, float *r_face_normal) { const Span positions = pbvh->vert_positions; - const int *corner_verts = pbvh->corner_verts; - const int *looptris = node->prim_indices; - int looptris_num = node->totprim; + const Span corner_verts = pbvh->corner_verts; bool hit = false; float nearest_vertex_co[3] = {0.0f}; - for (int i = 0; i < looptris_num; i++) { - const int looptri_i = looptris[i]; + for (const int i : node->prim_indices.index_range()) { + const int looptri_i = node->prim_indices[i]; const MLoopTri *lt = &pbvh->looptri[looptri_i]; - const int *face_verts = node->face_vert_indices[i]; + const blender::int3 face_verts = node->face_vert_indices[i]; - if (paint_is_face_hidden(pbvh->looptri_faces, pbvh->hide_poly, looptri_i)) { + if (paint_is_face_hidden(pbvh->looptri_faces.data(), pbvh->hide_poly, looptri_i)) { continue; } @@ -2511,7 +2441,7 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh, int *r_active_grid_index, float *r_face_normal) { - const int totgrid = node->totprim; + const int totgrid = node->prim_indices.size(); const int gridsize = pbvh->gridkey.grid_size; bool hit = false; float nearest_vertex_co[3] = {0.0}; @@ -2656,7 +2586,7 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, void BKE_pbvh_clip_ray_ortho( PBVH *pbvh, bool original, float ray_start[3], float ray_end[3], float ray_normal[3]) { - if (pbvh->nodes) { + if (!pbvh->nodes.is_empty()) { float rootmin_start, rootmin_end; float bb_min_root[3], bb_max_root[3], bb_center[3], bb_diff[3]; IsectRayAABB_Precalc ray; @@ -2665,10 +2595,10 @@ void BKE_pbvh_clip_ray_ortho( const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f}; if (original) { - BKE_pbvh_node_get_original_BB(pbvh->nodes, bb_min_root, bb_max_root); + BKE_pbvh_node_get_original_BB(&pbvh->nodes.first(), bb_min_root, bb_max_root); } else { - BKE_pbvh_node_get_BB(pbvh->nodes, bb_min_root, bb_max_root); + BKE_pbvh_node_get_BB(&pbvh->nodes.first(), bb_min_root, bb_max_root); } /* Calc rough clipping to avoid overflow later. See #109555. */ @@ -2792,17 +2722,15 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, float *dist_sq) { const Span positions = pbvh->vert_positions; - const int *corner_verts = pbvh->corner_verts; - const int *looptris = node->prim_indices; - int i, looptris_num = node->totprim; + const Span corner_verts = pbvh->corner_verts; bool hit = false; - for (i = 0; i < looptris_num; i++) { - const int looptri_i = looptris[i]; + for (const int i : node->prim_indices.index_range()) { + const int looptri_i = node->prim_indices[i]; const MLoopTri *lt = &pbvh->looptri[looptri_i]; - const int *face_verts = node->face_vert_indices[i]; + const blender::int3 face_verts = node->face_vert_indices[i]; - if (paint_is_face_hidden(pbvh->looptri_faces, pbvh->hide_poly, looptri_i)) { + if (paint_is_face_hidden(pbvh->looptri_faces.data(), pbvh->hide_poly, looptri_i)) { continue; } @@ -2839,7 +2767,7 @@ static bool pbvh_grids_node_nearest_to_ray(PBVH *pbvh, float *depth, float *dist_sq) { - const int totgrid = node->totprim; + const int totgrid = node->prim_indices.size(); const int gridsize = pbvh->gridkey.grid_size; bool hit = false; @@ -3109,23 +3037,19 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh, { PBVHNodeFlags flag = PBVH_Leaf; - for (int a = 0; a < pbvh->totnode; a++) { - PBVHNode *node = &pbvh->nodes[a]; - - if (node->flag & PBVH_TexLeaf) { + for (PBVHNode &node : pbvh->nodes) { + if (node.flag & PBVH_TexLeaf) { flag = PBVH_TexLeaf; break; } } - for (int a = 0; a < pbvh->totnode; a++) { - PBVHNode *node = &pbvh->nodes[a]; - - if (!(node->flag & flag)) { + for (PBVHNode &node : pbvh->nodes) { + if (!(node.flag & flag)) { continue; } - draw_fn(node, user_data, node->vb.bmin, node->vb.bmax, node->flag); + draw_fn(&node, user_data, node.vb.bmin, node.vb.bmax, node.flag); } } @@ -3144,8 +3068,8 @@ void BKE_pbvh_grids_update(PBVH *pbvh, pbvh->grid_flag_mats = flagmats; pbvh->grid_hidden = grid_hidden; - for (int a = 0; a < pbvh->totnode; a++) { - BKE_pbvh_node_mark_rebuild_draw(&pbvh->nodes[a]); + for (PBVHNode &node : pbvh->nodes) { + BKE_pbvh_node_mark_rebuild_draw(&node); } } } @@ -3196,8 +3120,8 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int } } - for (int a = 0; a < pbvh->totnode; a++) { - BKE_pbvh_node_mark_update(&pbvh->nodes[a]); + for (PBVHNode &node : pbvh->nodes) { + BKE_pbvh_node_mark_update(&node); } BKE_pbvh_update_bounds(pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB); @@ -3453,7 +3377,7 @@ void BKE_pbvh_node_num_loops(PBVH *pbvh, PBVHNode *node, int *r_totloop) BLI_assert(BKE_pbvh_type(pbvh) == PBVH_FACES); if (r_totloop) { - *r_totloop = node->loop_indices_num; + *r_totloop = node->loop_indices.size(); } } @@ -3474,44 +3398,42 @@ void BKE_pbvh_ensure_node_loops(PBVH *pbvh) int totloop = 0; /* Check if nodes already have loop indices. */ - for (int i = 0; i < pbvh->totnode; i++) { - PBVHNode *node = pbvh->nodes + i; - - if (!(node->flag & PBVH_Leaf)) { + for (PBVHNode &node : pbvh->nodes) { + if (!(node.flag & PBVH_Leaf)) { continue; } - if (node->loop_indices) { + if (!node.loop_indices.is_empty()) { return; } - totloop += node->totprim * 3; + totloop += node.prim_indices.size() * 3; } BLI_bitmap *visit = BLI_BITMAP_NEW(totloop, __func__); /* Create loop indices from node loop triangles. */ - for (int i = 0; i < pbvh->totnode; i++) { - PBVHNode *node = pbvh->nodes + i; - - if (!(node->flag & PBVH_Leaf)) { + Vector loop_indices; + for (PBVHNode &node : pbvh->nodes) { + if (!(node.flag & PBVH_Leaf)) { continue; } - node->loop_indices = static_cast( - MEM_malloc_arrayN(node->totprim * 3, sizeof(int), __func__)); - node->loop_indices_num = 0; + loop_indices.clear(); - for (int j = 0; j < node->totprim; j++) { - const MLoopTri *mlt = pbvh->looptri + node->prim_indices[j]; + for (const int i : node.prim_indices) { + const MLoopTri &mlt = pbvh->looptri[i]; for (int k = 0; k < 3; k++) { - if (!BLI_BITMAP_TEST(visit, mlt->tri[k])) { - node->loop_indices[node->loop_indices_num++] = mlt->tri[k]; - BLI_BITMAP_ENABLE(visit, mlt->tri[k]); + if (!BLI_BITMAP_TEST(visit, mlt.tri[k])) { + loop_indices.append(mlt.tri[k]); + BLI_BITMAP_ENABLE(visit, mlt.tri[k]); } } } + + node.loop_indices.reinitialize(loop_indices.size()); + node.loop_indices.as_mutable_span().copy_from(loop_indices); } MEM_SAFE_FREE(visit); @@ -3591,7 +3513,7 @@ static void pbvh_face_iter_step(PBVHFaceIter *fd, bool do_step) if (do_step) { fd->prim_index_++; - while (fd->prim_index_ < fd->node_->totprim) { + while (fd->prim_index_ < fd->node_->prim_indices.size()) { face_i = face_iter_prim_to_face(fd, fd->node_->prim_indices[fd->prim_index_]); if (face_i != fd->last_face_index_) { @@ -3601,17 +3523,17 @@ static void pbvh_face_iter_step(PBVHFaceIter *fd, bool do_step) fd->prim_index_++; } } - else if (fd->prim_index_ < fd->node_->totprim) { + else if (fd->prim_index_ < fd->node_->prim_indices.size()) { face_i = face_iter_prim_to_face(fd, fd->node_->prim_indices[fd->prim_index_]); } - if (fd->prim_index_ >= fd->node_->totprim) { + if (fd->prim_index_ >= fd->node_->prim_indices.size()) { return; } fd->last_face_index_ = face_i; - const int poly_start = fd->face_offsets_[face_i]; - const int poly_size = fd->face_offsets_[face_i + 1] - poly_start; + const int poly_start = fd->face_offsets_[face_i].start(); + const int poly_size = fd->face_offsets_[face_i].size(); fd->face.i = fd->index = face_i; @@ -3648,7 +3570,7 @@ void BKE_pbvh_face_iter_step(PBVHFaceIter *fd) void BKE_pbvh_face_iter_init(PBVH *pbvh, PBVHNode *node, PBVHFaceIter *fd) { - memset(fd, 0, sizeof(*fd)); + *fd = {}; fd->node_ = node; fd->pbvh_type_ = BKE_pbvh_type(pbvh); @@ -3661,7 +3583,7 @@ void BKE_pbvh_face_iter_init(PBVH *pbvh, PBVHNode *node, PBVHFaceIter *fd) fd->subdiv_key_ = pbvh->gridkey; ATTR_FALLTHROUGH; case PBVH_FACES: - fd->face_offsets_ = pbvh->faces.data(); + fd->face_offsets_ = pbvh->faces; fd->corner_verts_ = pbvh->corner_verts; fd->looptri_faces_ = pbvh->looptri_faces; fd->hide_poly_ = pbvh->hide_poly; @@ -3697,7 +3619,7 @@ bool BKE_pbvh_face_iter_done(PBVHFaceIter *fd) switch (fd->pbvh_type_) { case PBVH_FACES: case PBVH_GRIDS: - return fd->prim_index_ >= fd->node_->totprim; + return fd->prim_index_ >= fd->node_->prim_indices.size(); case PBVH_BMESH: return BLI_gsetIterator_done(&fd->bm_faces_iter_); default: @@ -3819,11 +3741,9 @@ Vector gather_proxies(PBVH *pbvh) { Vector array; - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = pbvh->nodes + n; - - if (node->proxy_count > 0) { - array.append(node); + for (PBVHNode &node : pbvh->nodes) { + if (node.proxy_count > 0) { + array.append(&node); } } diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.cc b/source/blender/blenkernel/intern/pbvh_bmesh.cc index 65f8e5bd69b..de3465c7f5c 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.cc +++ b/source/blender/blenkernel/intern/pbvh_bmesh.cc @@ -275,9 +275,9 @@ static void pbvh_bmesh_node_split(PBVH *pbvh, const BBC *bbc_array, int node_ind const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f; /* Add two new child nodes */ - const int children = pbvh->totnode; + const int children = pbvh->nodes.size(); n->children_offset = children; - pbvh_grow_nodes(pbvh, pbvh->totnode + 2); + pbvh_grow_nodes(pbvh, pbvh->nodes.size() + 2); /* Array reallocated, update current node pointer */ n = &pbvh->nodes[node_index]; @@ -456,7 +456,7 @@ BLI_INLINE int pbvh_bmesh_node_index_from_vert(PBVH *pbvh, const BMVert *key) { const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh->cd_vert_node_offset); BLI_assert(node_index != DYNTOPO_NODE_NONE); - BLI_assert(node_index < pbvh->totnode); + BLI_assert(node_index < pbvh->nodes.size()); return node_index; } @@ -464,7 +464,7 @@ BLI_INLINE int pbvh_bmesh_node_index_from_face(PBVH *pbvh, const BMFace *key) { const int node_index = BM_ELEM_CD_GET_INT((const BMElem *)key, pbvh->cd_face_node_offset); BLI_assert(node_index != DYNTOPO_NODE_NONE); - BLI_assert(node_index < pbvh->totnode); + BLI_assert(node_index < pbvh->nodes.size()); return node_index; } @@ -486,7 +486,7 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh, { PBVHNode *node = &pbvh->nodes[node_index]; - BLI_assert((pbvh->totnode == 1 || node_index) && node_index <= pbvh->totnode); + BLI_assert((pbvh->nodes.size() == 1 || node_index) && node_index <= pbvh->nodes.size()); /* avoid initializing customdata because its quite involved */ BMVert *v = BM_vert_create(pbvh->header.bm, co, nullptr, BM_CREATE_SKIP_CD); @@ -607,7 +607,7 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *pbvh, PBVHNode *new_owner, BLI_gset_remove(current_owner->bm_unique_verts, v, nullptr); /* Set new ownership */ - BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, new_owner - pbvh->nodes); + BM_ELEM_CD_SET_INT(v, pbvh->cd_vert_node_offset, new_owner - pbvh->nodes.data()); BLI_gset_insert(new_owner->bm_unique_verts, v); BLI_gset_remove(new_owner->bm_other_verts, v, nullptr); BLI_assert(!BLI_gset_haskey(new_owner->bm_other_verts, v)); @@ -1022,17 +1022,15 @@ static void long_edge_queue_create(EdgeQueueContext *eq_ctx, pbvh_bmesh_edge_tag_verify(pbvh); #endif - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - + for (PBVHNode &node : pbvh->nodes) { /* Check leaf nodes marked for topology update */ - if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) && - !(node->flag & PBVH_FullyHidden)) + if ((node.flag & PBVH_Leaf) && (node.flag & PBVH_UpdateTopology) && + !(node.flag & PBVH_FullyHidden)) { GSetIterator gs_iter; /* Check each face */ - GSET_ITER (gs_iter, node->bm_faces) { + GSET_ITER (gs_iter, node.bm_faces) { BMFace *f = static_cast(BLI_gsetIterator_getKey(&gs_iter)); long_edge_queue_face_add(eq_ctx, f); @@ -1082,17 +1080,15 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx, eq_ctx->q->edge_queue_tri_in_range = edge_queue_tri_in_sphere; } - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - + for (PBVHNode &node : pbvh->nodes) { /* Check leaf nodes marked for topology update */ - if ((node->flag & PBVH_Leaf) && (node->flag & PBVH_UpdateTopology) && - !(node->flag & PBVH_FullyHidden)) + if ((node.flag & PBVH_Leaf) && (node.flag & PBVH_UpdateTopology) && + !(node.flag & PBVH_FullyHidden)) { GSetIterator gs_iter; /* Check each face */ - GSET_ITER (gs_iter, node->bm_faces) { + GSET_ITER (gs_iter, node.bm_faces) { BMFace *f = static_cast(BLI_gsetIterator_getKey(&gs_iter)); short_edge_queue_face_add(eq_ctx, f); @@ -1356,7 +1352,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh, BLI_assert(!BM_face_exists(v_tri, 3)); BMEdge *e_tri[3]; PBVHNode *n = pbvh_bmesh_node_from_face(pbvh, f); - int ni = n - pbvh->nodes; + int ni = n - pbvh->nodes.data(); bm_edges_from_tri(pbvh->header.bm, v_tri, e_tri); pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f); @@ -1805,13 +1801,13 @@ static void pbvh_bmesh_node_limit_ensure_fast( static void pbvh_bmesh_create_nodes_fast_recursive( PBVH *pbvh, BMFace **nodeinfo, BBC *bbc_array, FastNodeBuildInfo *node, int node_index) { - PBVHNode *n = pbvh->nodes + node_index; + PBVHNode *n = &pbvh->nodes[node_index]; /* two cases, node does not have children or does have children */ if (node->child1) { - int children_offset = pbvh->totnode; + int children_offset = pbvh->nodes.size(); n->children_offset = children_offset; - pbvh_grow_nodes(pbvh, pbvh->totnode + 2); + pbvh_grow_nodes(pbvh, pbvh->nodes.size() + 2); pbvh_bmesh_create_nodes_fast_recursive( pbvh, nodeinfo, bbc_array, node->child1, children_offset); pbvh_bmesh_create_nodes_fast_recursive( @@ -1964,8 +1960,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh, * next we need to assign those to the gsets of the nodes. */ /* Start with all faces in the root node */ - pbvh->nodes = MEM_cnew(__func__); - pbvh->totnode = 1; + pbvh->nodes.append({}); /* take root node and visit and populate children recursively */ pbvh_bmesh_create_nodes_fast_recursive(pbvh, nodeinfo, bbc_array, &rootnode, 0); @@ -2035,27 +2030,23 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *pbvh, } /* Unmark nodes. */ - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - - if (node->flag & PBVH_Leaf && node->flag & PBVH_UpdateTopology) { - node->flag &= ~PBVH_UpdateTopology; + for (PBVHNode &node : pbvh->nodes) { + if (node.flag & PBVH_Leaf && node.flag & PBVH_UpdateTopology) { + node.flag &= ~PBVH_UpdateTopology; } } BLI_buffer_free(&edge_loops); BLI_buffer_free(&deleted_faces); /* Go over all changed nodes and check if anything needs to be updated. */ - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; + for (PBVHNode &node : pbvh->nodes) { + if (node.flag & PBVH_Leaf && node.flag & PBVH_TopologyUpdated) { + node.flag &= ~PBVH_TopologyUpdated; - if (node->flag & PBVH_Leaf && node->flag & PBVH_TopologyUpdated) { - node->flag &= ~PBVH_TopologyUpdated; - - if (node->bm_ortri) { + if (node.bm_ortri) { /* Reallocate original triangle data. */ - pbvh_bmesh_node_drop_orig(node); - BKE_pbvh_bmesh_node_save_orig(pbvh->header.bm, pbvh->bm_log, node, true); + pbvh_bmesh_node_drop_orig(&node); + BKE_pbvh_bmesh_node_save_orig(pbvh->header.bm, pbvh->bm_log, &node, true); } } } @@ -2147,7 +2138,8 @@ void BKE_pbvh_bmesh_node_save_orig(BMesh *bm, BMLog *log, PBVHNode *node, bool u void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh) { - for (int i = 0; i < pbvh->totnode; i++) { + const int totnode = pbvh->nodes.size(); + for (int i = 0; i < totnode; i++) { PBVHNode *n = &pbvh->nodes[i]; if (n->flag & PBVH_Leaf) { /* Free orco/ortri data */ diff --git a/source/blender/blenkernel/intern/pbvh_colors.cc b/source/blender/blenkernel/intern/pbvh_colors.cc index edda80c77e3..80514d7bc28 100644 --- a/source/blender/blenkernel/intern/pbvh_colors.cc +++ b/source/blender/blenkernel/intern/pbvh_colors.cc @@ -96,7 +96,7 @@ static void pbvh_vertex_color_get(const PBVH &pbvh, PBVHVertRef vertex, float r_ for (const int i_face : pbvh.pmap[index]) { const IndexRange face = pbvh.faces[i_face]; Span colors{static_cast(pbvh.color_layer->data) + face.start(), face.size()}; - Span face_verts{pbvh.corner_verts + face.start(), face.size()}; + Span face_verts = pbvh.corner_verts.slice(face); for (const int i : IndexRange(face.size())) { if (face_verts[i] == index) { @@ -127,7 +127,7 @@ static void pbvh_vertex_color_set(PBVH &pbvh, PBVHVertRef vertex, const float co for (const int i_face : pbvh.pmap[index]) { const IndexRange face = pbvh.faces[i_face]; MutableSpan colors{static_cast(pbvh.color_layer->data) + face.start(), face.size()}; - Span face_verts{pbvh.corner_verts + face.start(), face.size()}; + Span face_verts = pbvh.corner_verts.slice(face); for (const int i : IndexRange(face.size())) { if (face_verts[i] == index) { diff --git a/source/blender/blenkernel/intern/pbvh_intern.hh b/source/blender/blenkernel/intern/pbvh_intern.hh index 87080f0ce14..0e67b6cd8a9 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.hh +++ b/source/blender/blenkernel/intern/pbvh_intern.hh @@ -4,10 +4,13 @@ #pragma once +#include "BLI_array.hh" #include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_vector.hh" +#include "DNA_meshdata_types.h" + /** \file * \ingroup bke */ @@ -29,15 +32,15 @@ struct BBC { * union'd structs */ struct PBVHNode { /* Opaque handle for drawing code */ - PBVHBatches *draw_batches; + PBVHBatches *draw_batches = nullptr; /* Voxel bounds */ - BB vb; - BB orig_vb; + BB vb = {}; + BB orig_vb = {}; /* For internal nodes, the offset of the children in the PBVH * 'nodes' array. */ - int children_offset; + int children_offset = 0; /* List of primitives for this node. Semantics depends on * PBVH type: @@ -49,8 +52,7 @@ struct PBVHNode { * NOTE: This is a pointer inside of PBVH.prim_indices; it * is not allocated separately per node. */ - int *prim_indices; - unsigned int totprim; /* Number of primitives inside prim_indices. */ + blender::Span prim_indices; /* Array of indices into the mesh's vertex array. Contains the * indices of all vertices used by faces that are within this @@ -71,14 +73,14 @@ struct PBVHNode { * * Used for leaf nodes in a mesh-based PBVH (not multires.) */ - const int *vert_indices; - unsigned int uniq_verts, face_verts; + blender::Array vert_indices; + int uniq_verts = 0; + int face_verts = 0; /* Array of indices into the Mesh's corner array. * PBVH_FACES only. */ - int *loop_indices; - unsigned int loop_indices_num; + blender::Array loop_indices; /* An array mapping face corners into the vert_indices * array. The array is sized to match 'totprim', and each of @@ -88,20 +90,20 @@ struct PBVHNode { * * Used for leaf nodes in a mesh-based PBVH (not multires.) */ - const int (*face_vert_indices)[3]; + blender::Array face_vert_indices; /* Indicates whether this node is a leaf or not; also used for * marking various updates that need to be applied. */ - PBVHNodeFlags flag; + PBVHNodeFlags flag = PBVHNodeFlags(0); /* Used for ray-casting: how close the bounding-box is to the ray point. */ - float tmin; + float tmin = 0.0f; /* Scalar displacements for sculpt mode's layer brush. */ - float *layer_disp; + float *layer_disp = nullptr; - int proxy_count; - PBVHProxyNode *proxies; + int proxy_count = 0; + PBVHProxyNode *proxies = nullptr; /* Dyntopo */ @@ -109,15 +111,15 @@ struct PBVHNode { * NOTE: PBVH_BMESH only. Faces are always triangles * (dynamic topology forcibly triangulates the mesh). */ - GSet *bm_faces; - GSet *bm_unique_verts; - GSet *bm_other_verts; + GSet *bm_faces = nullptr; + GSet *bm_unique_verts = nullptr; + GSet *bm_other_verts = nullptr; /* Deprecated. Stores original coordinates of triangles. */ - float (*bm_orco)[3]; - int (*bm_ortri)[3]; - BMVert **bm_orvert; - int bm_tot_ortri; + float (*bm_orco)[3] = nullptr; + int (*bm_ortri)[3] = nullptr; + BMVert **bm_orvert = nullptr; + int bm_tot_ortri = 0; /* Used to store the brush color during a stroke and composite it over the original color */ PBVHColorBufferNode color_buffer; @@ -126,7 +128,7 @@ struct PBVHNode { /* Used to flash colors of updated node bounding boxes in * debug draw mode (when G.debug_value / bpy.app.debug_value is 889). */ - int debug_draw_gen; + int debug_draw_gen = 0; }; enum PBVHFlags { @@ -140,11 +142,10 @@ struct PBVH { PBVHPublic header; PBVHFlags flags; - PBVHNode *nodes; - int node_mem_count, totnode; + blender::Vector nodes; /* Memory backing for PBVHNode.prim_indices. */ - int *prim_indices; + blender::Array prim_indices; int totprim; int totvert; int faces_num; /* Do not use directly, use BKE_pbvh_num_faces. */ @@ -166,10 +167,10 @@ struct PBVH { blender::OffsetIndices faces; bool *hide_poly; /** Only valid for polygon meshes. */ - const int *corner_verts; + blender::Span corner_verts; /* Owned by the #PBVH, because after deformations they have to be recomputed. */ - const MLoopTri *looptri; - const int *looptri_faces; + blender::Array looptri; + blender::Span looptri_faces; CustomData *vert_data; CustomData *loop_data; CustomData *face_data; @@ -188,7 +189,7 @@ struct PBVH { /* Used during BVH build and later to mark that a vertex needs to update * (its normal must be recalculated). */ - bool *vert_bitmap; + blender::Array vert_bitmap; #ifdef PERFCNTRS int perf_modified; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 0f5d32b62d9..8092d1ed9f4 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -274,9 +274,9 @@ static void split_flush_final_nodes(SplitQueueData *tdata) } if (!newsplit->parent->children_offset) { - newsplit->parent->children_offset = pbvh->totnode; + newsplit->parent->children_offset = pbvh->nodes.size(); - pbvh_grow_nodes(pbvh, pbvh->totnode + 2); + pbvh_grow_nodes(pbvh, pbvh->nodes.size() + 2); newsplit->source_index = newsplit->parent->children_offset; } else { @@ -331,7 +331,7 @@ static void split_pixel_nodes(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *i tdata.new_nodes = BLI_thread_queue_init(); /* Set up initial jobs before initializing threads. */ - for (int i : IndexRange(pbvh->totnode)) { + for (const int i : pbvh->nodes.index_range()) { if (pbvh->nodes[i].flag & PBVH_TexLeaf) { SplitNodePair *split = MEM_new("split_pixel_nodes split"); @@ -481,9 +481,7 @@ static void do_encode_pixels(void *__restrict userdata, tile_data.tile_number = image_tile.get_tile_number(); float2 tile_offset = float2(image_tile.get_tile_offset()); - for (int pbvh_node_prim_index = 0; pbvh_node_prim_index < node->totprim; - pbvh_node_prim_index++) { - int64_t geom_prim_index = node->prim_indices[pbvh_node_prim_index]; + for (const int geom_prim_index : node->prim_indices) { for (const UVPrimitiveLookup::Entry &entry : data->uv_primitive_lookup->lookup[geom_prim_index]) { uv_islands::UVBorder uv_border = entry.uv_primitive->extract_border(); @@ -555,9 +553,8 @@ static bool should_pixels_be_updated(PBVHNode *node) static int64_t count_nodes_to_update(PBVH *pbvh) { int64_t result = 0; - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - if (should_pixels_be_updated(node)) { + for (PBVHNode &node : pbvh->nodes) { + if (should_pixels_be_updated(&node)) { result++; } } @@ -592,20 +589,19 @@ static bool find_nodes_to_update(PBVH *pbvh, Vector &r_nodes_to_upda r_nodes_to_update.reserve(nodes_to_update_len); - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - if (!should_pixels_be_updated(node)) { + for (PBVHNode &node : pbvh->nodes) { + if (!should_pixels_be_updated(&node)) { continue; } - r_nodes_to_update.append(node); - node->flag = static_cast(node->flag | PBVH_RebuildPixels); + r_nodes_to_update.append(&node); + node.flag = static_cast(node.flag | PBVH_RebuildPixels); - if (node->pixels.node_data == nullptr) { + if (node.pixels.node_data == nullptr) { NodeData *node_data = MEM_new(__func__); - node->pixels.node_data = node_data; + node.pixels.node_data = node_data; } else { - NodeData *node_data = static_cast(node->pixels.node_data); + NodeData *node_data = static_cast(node.pixels.node_data); node_data->clear_data(); } } @@ -623,12 +619,11 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us if (image_buffer == nullptr) { continue; } - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = &pbvh->nodes[n]; - if ((node->flag & PBVH_Leaf) == 0) { + for (PBVHNode &node : pbvh->nodes) { + if ((node.flag & PBVH_Leaf) == 0) { continue; } - NodeData *node_data = static_cast(node->pixels.node_data); + NodeData *node_data = static_cast(node.pixels.node_data); UDIMTilePixels *tile_node_data = node_data->find_tile_data(image_tile); if (tile_node_data == nullptr) { continue; @@ -671,10 +666,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image const AttributeAccessor attributes = mesh->attributes(); const VArraySpan uv_map = *attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); - uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim}, - {pbvh->corner_verts, mesh->totloop}, - uv_map, - pbvh->vert_positions); + uv_islands::MeshData mesh_data(pbvh->looptri, pbvh->corner_verts, uv_map, pbvh->vert_positions); uv_islands::UVIslands islands(mesh_data); uv_islands::UVIslandsMask uv_masks; @@ -730,9 +722,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image } /* Add PBVH_TexLeaf flag */ - for (int i : IndexRange(pbvh->totnode)) { - PBVHNode &node = pbvh->nodes[i]; - + for (PBVHNode &node : pbvh->nodes) { if (node.flag & PBVH_Leaf) { node.flag = (PBVHNodeFlags)(int(node.flag) | int(PBVH_TexLeaf)); } diff --git a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc index 8e54816feaa..1f9e5d78910 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels_copy.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels_copy.cc @@ -175,7 +175,7 @@ class PixelNodesTileData : public Vector> { reserve(count_nodes(pbvh, image_tile)); - for (PBVHNode &node : MutableSpan(pbvh.nodes, pbvh.totnode)) { + for (PBVHNode &node : pbvh.nodes) { if (should_add_node(node, image_tile)) { NodeData &node_data = *static_cast(node.pixels.node_data); UDIMTilePixels &tile_pixels = *node_data.find_tile_data(image_tile); @@ -203,7 +203,7 @@ class PixelNodesTileData : public Vector> static int64_t count_nodes(PBVH &pbvh, const image::ImageTileWrapper &image_tile) { int64_t result = 0; - for (PBVHNode &node : MutableSpan(pbvh.nodes, pbvh.totnode)) { + for (PBVHNode &node : pbvh.nodes) { if (should_add_node(node, image_tile)) { result++; } diff --git a/source/blender/draw/DRW_pbvh.hh b/source/blender/draw/DRW_pbvh.hh index 8556d143b87..eb294a0213f 100644 --- a/source/blender/draw/DRW_pbvh.hh +++ b/source/blender/draw/DRW_pbvh.hh @@ -57,19 +57,18 @@ struct PBVH_GPU_Args { SubdivCCG *subdiv_ccg; const DMFlagMat *grid_flag_mats; - const int *grid_indices; + blender::Span grid_indices; CCGKey ccg_key; CCGElem **grids; void **gridfaces; BLI_bitmap **grid_hidden; - const int *prim_indices; - int totprim; + blender::Span prim_indices; const bool *hide_poly; - const MLoopTri *mlooptri; - const int *looptri_faces; + blender::Span mlooptri; + blender::Span looptri_faces; PBVHNode *node; /* BMesh. */ diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 4352cc3fe68..7f6fc744979 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -191,8 +191,7 @@ struct PBVHBatches { switch (args->pbvh_type) { case PBVH_FACES: { - for (int i = 0; i < args->totprim; i++) { - const int looptri_i = args->prim_indices[i]; + for (const int looptri_i : args->prim_indices) { const int face_i = args->looptri_faces[looptri_i]; if (args->hide_poly && args->hide_poly[face_i]) { @@ -205,8 +204,8 @@ struct PBVHBatches { } case PBVH_GRIDS: { count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden, - args->grid_indices, - args->totprim, + args->grid_indices.data(), + args->grid_indices.size(), args->ccg_key.grid_size, args->ccg_key.grid_size); @@ -366,7 +365,7 @@ struct PBVHBatches { foreach_grids) { uint vert_per_grid = square_i(args->ccg_key.grid_size - 1) * 4; - uint vert_count = args->totprim * vert_per_grid; + uint vert_count = args->grid_indices.size() * vert_per_grid; int existing_num = GPU_vertbuf_get_vertex_len(vbo.vert_buf); void *existing_data = GPU_vertbuf_get_data(vbo.vert_buf); @@ -482,7 +481,7 @@ struct PBVHBatches { { int gridsize = args->ccg_key.grid_size; - uint totgrid = args->totprim; + uint totgrid = args->grid_indices.size(); auto foreach_solid = [&](std::function func) { @@ -550,8 +549,7 @@ struct PBVHBatches { func) { int buffer_i = 0; - for (int i : IndexRange(args->totprim)) { - const int looptri_i = args->prim_indices[i]; + for (const int looptri_i : args->prim_indices) { const int face_i = args->looptri_faces[looptri_i]; if (args->hide_poly && args->hide_poly[face_i]) { @@ -973,7 +971,7 @@ struct PBVHBatches { const int *mat_index = static_cast( CustomData_get_layer_named(args->face_data, CD_PROP_INT32, "material_index")); - if (mat_index && args->totprim) { + if (mat_index && !args->prim_indices.is_empty()) { const int looptri_i = args->prim_indices[0]; const int face_i = args->looptri_faces[looptri_i]; material_index = mat_index[face_i]; @@ -983,8 +981,7 @@ struct PBVHBatches { /* Calculate number of edges. */ int edge_count = 0; - for (int i = 0; i < args->totprim; i++) { - const int looptri_i = args->prim_indices[i]; + for (const int looptri_i : args->prim_indices) { const int face_i = args->looptri_faces[looptri_i]; if (args->hide_poly && args->hide_poly[face_i]) { continue; @@ -1010,8 +1007,7 @@ struct PBVHBatches { GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, edge_count * 2, INT_MAX); int vertex_i = 0; - for (int i = 0; i < args->totprim; i++) { - const int looptri_i = args->prim_indices[i]; + for (const int looptri_i : args->prim_indices) { const int face_i = args->looptri_faces[looptri_i]; if (args->hide_poly && args->hide_poly[face_i]) { continue; @@ -1068,7 +1064,7 @@ struct PBVHBatches { const int *mat_index = static_cast( CustomData_get_layer_named(args->face_data, CD_PROP_INT32, "material_index")); - if (mat_index && args->totprim) { + if (mat_index && !args->grid_indices.is_empty()) { int face_i = BKE_subdiv_ccg_grid_to_face_index(args->subdiv_ccg, args->grid_indices[0]); material_index = mat_index[face_i]; } @@ -1076,7 +1072,7 @@ struct PBVHBatches { needs_tri_index = true; int gridsize = args->ccg_key.grid_size; int display_gridsize = gridsize; - int totgrid = args->totprim; + int totgrid = args->grid_indices.size(); int skip = 1; const int display_level = do_coarse ? coarse_level : args->ccg_key.level; @@ -1086,8 +1082,7 @@ struct PBVHBatches { skip = 1 << (args->ccg_key.level - display_level - 1); } - for (int i : IndexRange(args->totprim)) { - int grid_index = args->grid_indices[i]; + for (const int grid_index : args->grid_indices) { bool smooth = !args->grid_flag_mats[grid_index].sharp; BLI_bitmap *gh = args->grid_hidden[grid_index]; @@ -1114,7 +1109,7 @@ struct PBVHBatches { CCGKey *key = &args->ccg_key; uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden, - args->grid_indices, + args->grid_indices.data(), totgrid, key->grid_size, display_gridsize);