From b86fc55d30054d454c2d3c8bf0f91fdfbb5d0a29 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 14 Apr 2023 21:16:42 +0200 Subject: [PATCH] Cleanup: Use Vector for passing lists of PBVHNodes around Cleaned up sculpt code to store lists of `PBVHNodes` with `blender::Vector` instead of simple pointer arrays. This is much simpler and eliminates memory leaks caused by forgetting to free the result of `BKE_pbvh_search_gather`. Notes: * `BKE_pbvh_search_gather` is now `blender::pbvh::search_gather`. * `FilterCache` and `ExpandCache` have ownership over their .nodes members; as a result they're no longer pure C structs and are allocated with `MEM_new`/`MEM_delete`. * The word 'totnode' no longer occurs anywhere in `source/blender/editors/sculpt_paint` Todo (not for this PR): create a new properly C++ task API for sculpt (with lambdas) and use it for brushes. Pull Request: https://projects.blender.org/blender/blender/pulls/106884 --- source/blender/blenkernel/BKE_pbvh.h | 22 +- source/blender/blenkernel/intern/paint.cc | 13 +- source/blender/blenkernel/intern/pbvh.cc | 320 +++++++----------- .../blender/blenkernel/intern/pbvh_bmesh.cc | 9 +- .../blender/blenkernel/intern/pbvh_intern.hh | 4 +- .../editors/sculpt_paint/paint_hide.cc | 24 +- .../editors/sculpt_paint/paint_mask.cc | 64 ++-- .../editors/sculpt_paint/paint_vertex.cc | 114 +++---- .../sculpt_paint/paint_vertex_color_ops.cc | 13 +- source/blender/editors/sculpt_paint/sculpt.cc | 315 +++++++---------- .../editors/sculpt_paint/sculpt_boundary.cc | 22 +- .../sculpt_paint/sculpt_brush_types.cc | 184 +++++----- .../editors/sculpt_paint/sculpt_cloth.cc | 109 +++--- .../editors/sculpt_paint/sculpt_detail.cc | 15 +- .../editors/sculpt_paint/sculpt_expand.cc | 83 ++--- .../editors/sculpt_paint/sculpt_face_set.cc | 101 +++--- .../sculpt_paint/sculpt_filter_color.cc | 5 +- .../sculpt_paint/sculpt_filter_mask.cc | 24 +- .../sculpt_paint/sculpt_filter_mesh.cc | 47 +-- .../editors/sculpt_paint/sculpt_intern.hh | 132 ++++---- .../sculpt_paint/sculpt_mask_expand.cc | 40 +-- .../editors/sculpt_paint/sculpt_mask_init.cc | 11 +- .../sculpt_paint/sculpt_multiplane_scrape.cc | 16 +- .../editors/sculpt_paint/sculpt_ops.cc | 45 +-- .../sculpt_paint/sculpt_paint_color.cc | 35 +- .../sculpt_paint/sculpt_paint_image.cc | 24 +- .../editors/sculpt_paint/sculpt_pose.cc | 28 +- .../editors/sculpt_paint/sculpt_smooth.cc | 35 +- .../editors/sculpt_paint/sculpt_transform.cc | 22 +- .../editors/sculpt_paint/sculpt_undo.cc | 29 +- 30 files changed, 824 insertions(+), 1081 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index f11b295afa4..877f11d3069 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -12,6 +12,7 @@ #include "BLI_ghash.h" #ifdef __cplusplus # include "BLI_offset_indices.hh" +# include "BLI_vector.hh" #endif #include "bmesh.h" @@ -320,7 +321,8 @@ void BKE_pbvh_free(PBVH *pbvh); /* Hierarchical Search in the BVH, two methods: * - For each hit calling a callback. - * - Gather nodes in an array (easy to multi-thread). */ + * - Gather nodes in an array (easy to multi-thread) see blender::bke::pbvh::search_gather. + */ void BKE_pbvh_search_callback(PBVH *pbvh, BKE_pbvh_SearchCallback scb, @@ -328,14 +330,6 @@ void BKE_pbvh_search_callback(PBVH *pbvh, BKE_pbvh_HitCallback hcb, void *hit_data); -void BKE_pbvh_search_gather( - PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot); -void BKE_pbvh_search_gather_ex(PBVH *pbvh, - BKE_pbvh_SearchCallback scb, - void *search_data, - PBVHNode ***r_array, - int *r_tot, - PBVHNodeFlags leaf_flag); /* Ray-cast * the hit callback is called for all leaf nodes intersecting the ray; * it's up to the callback to find the primitive within the leaves that is @@ -748,7 +742,6 @@ void BKE_pbvh_face_iter_finish(PBVHFaceIter *fd); void BKE_pbvh_node_get_proxies(PBVHNode *node, PBVHProxyNode **proxies, int *proxy_count); void BKE_pbvh_node_free_proxies(PBVHNode *node); PBVHProxyNode *BKE_pbvh_node_add_proxy(PBVH *pbvh, PBVHNode *node); -void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot); void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node, int (**r_orco_tris)[3], int *r_orco_tris_num, @@ -826,4 +819,13 @@ int BKE_pbvh_debug_draw_gen_get(PBVHNode *node); #ifdef __cplusplus } + +namespace blender::bke::pbvh { +Vector search_gather(PBVH *pbvh, + BKE_pbvh_SearchCallback scb, + void *search_data, + PBVHNodeFlags leaf_flag = PBVH_Leaf); +Vector gather_proxies(PBVH *pbvh); + +} // namespace blender::bke::pbvh #endif diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 33fe483f815..22d91a927de 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -27,6 +27,7 @@ #include "BLI_math_vector.h" #include "BLI_string_utf8.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "BLT_translation.h" @@ -70,6 +71,7 @@ using blender::float3; using blender::MutableSpan; using blender::Span; +using blender::Vector; static void sculpt_attribute_update_refs(Object *ob); static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob, @@ -1891,16 +1893,11 @@ void BKE_sculpt_update_object_before_eval(Object *ob_eval) BKE_sculptsession_free_vwpaint_data(ob_eval->sculpt); } else { - PBVHNode **nodes; - int n, totnode; + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - - for (n = 0; n < totnode; n++) { - BKE_pbvh_node_mark_update(nodes[n]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update(node); } - - MEM_freeN(nodes); } } } diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index bb5b0f9ce6d..f4c26dcf7a8 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -14,6 +14,7 @@ #include "BLI_rand.h" #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -39,6 +40,7 @@ using blender::float3; using blender::MutableSpan; using blender::Span; +using blender::Vector; #define LEAF_LIMIT 10000 @@ -1225,70 +1227,6 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter) return nullptr; } -void BKE_pbvh_search_gather_ex(PBVH *pbvh, - BKE_pbvh_SearchCallback scb, - void *search_data, - PBVHNode ***r_array, - int *r_tot, - PBVHNodeFlags leaf_flag) -{ - PBVHIter iter; - PBVHNode **array = nullptr, *node; - int tot = 0, space = 0; - - pbvh_iter_begin(&iter, pbvh, scb, search_data); - - while ((node = pbvh_iter_next(&iter, leaf_flag))) { - if (node->flag & leaf_flag) { - if (UNLIKELY(tot == space)) { - /* resize array if needed */ - space = (tot == 0) ? 32 : space * 2; - array = static_cast( - MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__)); - } - - array[tot] = node; - tot++; - } - } - - pbvh_iter_end(&iter); - - if (tot == 0 && array) { - MEM_freeN(array); - array = nullptr; - } - - *r_array = array; - *r_tot = tot; -} - -void BKE_pbvh_search_gather( - PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot) -{ - BKE_pbvh_search_gather_ex(pbvh, scb, search_data, r_array, r_tot, PBVH_Leaf); -} - -void BKE_pbvh_search_callback(PBVH *pbvh, - BKE_pbvh_SearchCallback scb, - void *search_data, - BKE_pbvh_HitCallback hcb, - void *hit_data) -{ - PBVHIter iter; - PBVHNode *node; - - pbvh_iter_begin(&iter, pbvh, scb, search_data); - - while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) { - if (node->flag & PBVH_Leaf) { - hcb(node, hit_data); - } - } - - pbvh_iter_end(&iter); -} - struct node_tree { PBVHNode *data; @@ -1352,6 +1290,26 @@ float BKE_pbvh_node_get_tmin(PBVHNode *node) return node->tmin; } +void BKE_pbvh_search_callback(PBVH *pbvh, + BKE_pbvh_SearchCallback scb, + void *search_data, + BKE_pbvh_HitCallback hcb, + void *hit_data) +{ + PBVHIter iter; + PBVHNode *node; + + pbvh_iter_begin(&iter, pbvh, scb, search_data); + + while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) { + if (node->flag & PBVH_Leaf) { + hcb(node, hit_data); + } + } + + pbvh_iter_end(&iter); +} + static void BKE_pbvh_search_callback_occluded(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, @@ -1404,14 +1362,15 @@ static bool update_search_cb(PBVHNode *node, void *data_v) struct PBVHUpdateData { PBVH *pbvh; - PBVHNode **nodes; - int totnode; + Span nodes; - float (*vert_normals)[3]; - int flag; - bool show_sculpt_face_sets; - PBVHAttrReq *attrs; - int attrs_num; + float (*vert_normals)[3] = nullptr; + int flag = 0; + bool show_sculpt_face_sets = false; + PBVHAttrReq *attrs = nullptr; + int attrs_num = 0; + + PBVHUpdateData(PBVH *pbvh_, Span nodes_) : pbvh(pbvh_), nodes(nodes_) {} }; static void pbvh_update_normals_clear_task_cb(void *__restrict userdata, @@ -1515,7 +1474,7 @@ static void pbvh_update_normals_store_task_cb(void *__restrict userdata, } } -static void pbvh_faces_update_normals(PBVH *pbvh, PBVHNode **nodes, int totnode) +static void pbvh_faces_update_normals(PBVH *pbvh, Span nodes) { /* subtle assumptions: * - We know that for all edited vertices, the nodes with faces @@ -1527,18 +1486,18 @@ static void pbvh_faces_update_normals(PBVH *pbvh, PBVHNode **nodes, int totnode) * can only update vertices marked in the `vert_bitmap`. */ - PBVHUpdateData data{}; + PBVHUpdateData data(pbvh, nodes); data.pbvh = pbvh; data.nodes = nodes; data.vert_normals = pbvh->vert_normals; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); /* Zero normals before accumulation. */ - BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_clear_task_cb, &settings); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_accum_task_cb, &settings); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_normals_store_task_cb, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_normals_clear_task_cb, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_normals_accum_task_cb, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_normals_store_task_cb, &settings); } static void pbvh_update_mask_redraw_task_cb(void *__restrict userdata, @@ -1577,16 +1536,16 @@ static void pbvh_update_mask_redraw_task_cb(void *__restrict userdata, } } -static void pbvh_update_mask_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag) +static void pbvh_update_mask_redraw(PBVH *pbvh, Span nodes, int flag) { - PBVHUpdateData data{}; + PBVHUpdateData data(pbvh, nodes); data.pbvh = pbvh; data.nodes = nodes; data.flag = flag; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_mask_redraw_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_mask_redraw_task_cb, &settings); } static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata, @@ -1613,16 +1572,17 @@ static void pbvh_update_visibility_redraw_task_cb(void *__restrict userdata, } } -static void pbvh_update_visibility_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag) +static void pbvh_update_visibility_redraw(PBVH *pbvh, Span nodes, int flag) { - PBVHUpdateData data{}; + PBVHUpdateData data(pbvh, nodes); data.pbvh = pbvh; data.nodes = nodes; data.flag = flag; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_visibility_redraw_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range( + 0, nodes.size(), &data, pbvh_update_visibility_redraw_task_cb, &settings); } static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata, @@ -1649,17 +1609,15 @@ static void pbvh_update_BB_redraw_task_cb(void *__restrict userdata, } } -void pbvh_update_BB_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag) +static void pbvh_update_BB_redraw(PBVH *pbvh, Span nodes, int flag) { /* update BB, redraw flag */ - PBVHUpdateData data{}; - data.pbvh = pbvh; - data.nodes = nodes; + PBVHUpdateData data(pbvh, nodes); data.flag = flag; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_BB_redraw_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_BB_redraw_task_cb, &settings); } bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_attr) @@ -1724,7 +1682,7 @@ void pbvh_free_draw_buffers(PBVH * /*pbvh*/, PBVHNode *node) } } -static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, int update_flag) +static void pbvh_update_draw_buffers(PBVH *pbvh, Span nodes, int update_flag) { const CustomData *vdata; @@ -1748,8 +1706,7 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->header.type, PBVH_GRIDS, PBVH_BMESH)) { /* Free buffers uses OpenGL, so not in parallel. */ - for (int n = 0; n < totnode; n++) { - PBVHNode *node = nodes[n]; + for (PBVHNode *node : nodes) { if (node->flag & PBVH_RebuildDrawBuffers) { pbvh_free_draw_buffers(pbvh, node); } @@ -1763,17 +1720,13 @@ static void pbvh_update_draw_buffers(PBVH *pbvh, PBVHNode **nodes, int totnode, } /* Parallel creation and update of draw buffers. */ - PBVHUpdateData data{}; - data.pbvh = pbvh; - data.nodes = nodes; + PBVHUpdateData data(pbvh, nodes); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_draw_buffer_cb, &settings); - - for (int i = 0; i < totnode; i++) { - PBVHNode *node = nodes[i]; + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_draw_buffer_cb, &settings); + for (PBVHNode *node : nodes) { if (node->flag & PBVH_UpdateDrawBuffers) { /* Flush buffers uses OpenGL, so not in parallel. */ @@ -1824,20 +1777,16 @@ void BKE_pbvh_update_bounds(PBVH *pbvh, int flag) return; } - PBVHNode **nodes; - int totnode; - - BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather( + pbvh, update_search_cb, POINTER_FROM_INT(flag)); if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw)) { - pbvh_update_BB_redraw(pbvh, nodes, totnode, flag); + pbvh_update_BB_redraw(pbvh, nodes, flag); } if (flag & (PBVH_UpdateBB | PBVH_UpdateOriginalBB)) { pbvh_flush_bb(pbvh, pbvh->nodes, flag); } - - MEM_SAFE_FREE(nodes); } void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag) @@ -1846,27 +1795,21 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag) return; } - PBVHNode **nodes; - int totnode; - - BKE_pbvh_search_gather(pbvh, update_search_cb, POINTER_FROM_INT(flag), &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather( + pbvh, update_search_cb, POINTER_FROM_INT(flag)); if (flag & (PBVH_UpdateMask)) { - pbvh_update_mask_redraw(pbvh, nodes, totnode, flag); + pbvh_update_mask_redraw(pbvh, nodes, flag); } if (flag & (PBVH_UpdateColor)) { - for (int i = 0; i < totnode; i++) { - nodes[i]->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor; + for (PBVHNode *node : nodes) { + node->flag |= PBVH_UpdateRedraw | PBVH_UpdateDrawBuffers | PBVH_UpdateColor; } } if (flag & (PBVH_UpdateVisibility)) { - pbvh_update_visibility_redraw(pbvh, nodes, totnode, flag); - } - - if (nodes) { - MEM_freeN(nodes); + pbvh_update_visibility_redraw(pbvh, nodes, flag); } } @@ -1973,15 +1916,14 @@ static void pbvh_update_visibility_task_cb(void *__restrict userdata, } } -static void pbvh_update_visibility(PBVH *pbvh, PBVHNode **nodes, int totnode) +static void pbvh_update_visibility(PBVH *pbvh, Span nodes) { - PBVHUpdateData data{}; + PBVHUpdateData data(pbvh, nodes); data.pbvh = pbvh; - data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, pbvh_update_visibility_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, pbvh_update_visibility_task_cb, &settings); } void BKE_pbvh_update_visibility(PBVH *pbvh) @@ -1990,16 +1932,10 @@ void BKE_pbvh_update_visibility(PBVH *pbvh) return; } - PBVHNode **nodes; - int totnode; + Vector nodes = blender::bke::pbvh::search_gather( + pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateVisibility)); - BKE_pbvh_search_gather( - pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateVisibility), &nodes, &totnode); - pbvh_update_visibility(pbvh, nodes, totnode); - - if (nodes) { - MEM_freeN(nodes); - } + pbvh_update_visibility(pbvh, nodes); } void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3]) @@ -3095,18 +3031,15 @@ bool BKE_pbvh_node_frustum_exclude_AABB(PBVHNode *node, void *data) void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg) { /* Update normals */ - PBVHNode **nodes; - int totnode; + Vector nodes = blender::bke::pbvh::search_gather( + pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals)); - BKE_pbvh_search_gather( - pbvh, update_search_cb, POINTER_FROM_INT(PBVH_UpdateNormals), &nodes, &totnode); - - if (totnode > 0) { + if (!nodes.is_empty()) { if (pbvh->header.type == PBVH_BMESH) { - pbvh_bmesh_normals_update(nodes, totnode); + pbvh_bmesh_normals_update(nodes); } else if (pbvh->header.type == PBVH_FACES) { - pbvh_faces_update_normals(pbvh, nodes, totnode); + pbvh_faces_update_normals(pbvh, nodes); } else if (pbvh->header.type == PBVH_GRIDS) { CCGFace **faces; @@ -3118,8 +3051,6 @@ void BKE_pbvh_update_normals(PBVH *pbvh, SubdivCCG *subdiv_ccg) } } } - - MEM_SAFE_FREE(nodes); } void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default) @@ -3160,8 +3091,7 @@ void BKE_pbvh_draw_cb(PBVH *pbvh, PBVHAttrReq *attrs, int attrs_num) { - PBVHNode **nodes; - int totnode; + Vector nodes; int update_flag = 0; pbvh->draw_cache_invalid = false; @@ -3174,41 +3104,37 @@ void BKE_pbvh_draw_cb(PBVH *pbvh, data.accum_update_flag = 0; data.attrs = attrs; data.attrs_num = attrs_num; - BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &data, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(pbvh, pbvh_draw_search_cb, &data); update_flag = data.accum_update_flag; } else { /* Get all nodes with draw updates, also those outside the view. */ const int search_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers; - BKE_pbvh_search_gather( - pbvh, update_search_cb, POINTER_FROM_INT(search_flag), &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather( + pbvh, update_search_cb, POINTER_FROM_INT(search_flag)); update_flag = PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers; } /* Update draw buffers. */ - if (totnode != 0 && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) { - pbvh_update_draw_buffers(pbvh, nodes, totnode, update_flag); + if (!nodes.is_empty() && (update_flag & (PBVH_RebuildDrawBuffers | PBVH_UpdateDrawBuffers))) { + pbvh_update_draw_buffers(pbvh, nodes, update_flag); } - MEM_SAFE_FREE(nodes); /* Draw visible nodes. */ PBVHDrawSearchData draw_data{}; draw_data.frustum = draw_frustum; draw_data.accum_update_flag = 0; - BKE_pbvh_search_gather(pbvh, pbvh_draw_search_cb, &draw_data, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(pbvh, pbvh_draw_search_cb, &draw_data); PBVH_GPU_Args args; - for (int i = 0; i < totnode; i++) { - PBVHNode *node = nodes[i]; + for (PBVHNode *node : nodes) { if (!(node->flag & PBVH_FullyHidden)) { pbvh_draw_args_init(pbvh, &args, node); draw_fn(user_data, node->draw_batches, &args); } } - - MEM_SAFE_FREE(nodes); } void BKE_pbvh_draw_debug_cb(PBVH *pbvh, @@ -3357,36 +3283,6 @@ void BKE_pbvh_node_free_proxies(PBVHNode *node) node->proxy_count = 0; } -void BKE_pbvh_gather_proxies(PBVH *pbvh, PBVHNode ***r_array, int *r_tot) -{ - PBVHNode **array = nullptr; - int tot = 0, space = 0; - - for (int n = 0; n < pbvh->totnode; n++) { - PBVHNode *node = pbvh->nodes + n; - - if (node->proxy_count > 0) { - if (tot == space) { - /* resize array if needed */ - space = (tot == 0) ? 32 : space * 2; - array = static_cast( - MEM_recallocN_id(array, sizeof(PBVHNode *) * space, __func__)); - } - - array[tot] = node; - tot++; - } - } - - if (tot == 0 && array) { - MEM_freeN(array); - array = nullptr; - } - - *r_array = array; - *r_tot = tot; -} - PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node) { @@ -3399,13 +3295,11 @@ PBVHColorBufferNode *BKE_pbvh_node_color_buffer_get(PBVHNode *node) void BKE_pbvh_node_color_buffer_free(PBVH *pbvh) { - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); - for (int i = 0; i < totnode; i++) { - MEM_SAFE_FREE(nodes[i]->color_buffer.color); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); + + for (PBVHNode *node : nodes) { + MEM_SAFE_FREE(node->color_buffer.color); } - MEM_SAFE_FREE(nodes); } void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode) @@ -3934,3 +3828,41 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh) } } } + +namespace blender::bke::pbvh { +Vector search_gather(PBVH *pbvh, + BKE_pbvh_SearchCallback scb, + void *search_data, + PBVHNodeFlags leaf_flag) +{ + PBVHIter iter; + Vector nodes; + + pbvh_iter_begin(&iter, pbvh, scb, search_data); + + PBVHNode *node; + while ((node = pbvh_iter_next(&iter, leaf_flag))) { + if (node->flag & leaf_flag) { + nodes.append(node); + } + } + + pbvh_iter_end(&iter); + return nodes; +} + +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); + } + } + + return array; +} +} // namespace blender::bke::pbvh diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.cc b/source/blender/blenkernel/intern/pbvh_bmesh.cc index b5f5a3b7ce1..50c15164f5d 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.cc +++ b/source/blender/blenkernel/intern/pbvh_bmesh.cc @@ -11,6 +11,7 @@ #include "BLI_heap_simple.h" #include "BLI_math.h" #include "BLI_memarena.h" +#include "BLI_span.hh" #include "BLI_utildefines.h" #include "BKE_DerivedMesh.h" @@ -22,6 +23,8 @@ #include "bmesh.h" #include "pbvh_intern.hh" +using blender::Span; + /* Avoid skinny faces */ #define USE_EDGEQUEUE_EVEN_SUBDIV #ifdef USE_EDGEQUEUE_EVEN_SUBDIV @@ -1659,11 +1662,9 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node, return hit; } -void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode) +void pbvh_bmesh_normals_update(Span nodes) { - for (int n = 0; n < totnode; n++) { - PBVHNode *node = nodes[n]; - + for (PBVHNode *node : nodes) { if (node->flag & PBVH_UpdateNormals) { GSetIterator gs_iter; diff --git a/source/blender/blenkernel/intern/pbvh_intern.hh b/source/blender/blenkernel/intern/pbvh_intern.hh index 992be2ec2df..f714f03a580 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.hh +++ b/source/blender/blenkernel/intern/pbvh_intern.hh @@ -2,6 +2,8 @@ #pragma once +#include "BLI_vector.hh" + /** \file * \ingroup bke */ @@ -281,7 +283,7 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node, float *dist_sq, bool use_original); -void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode); +void pbvh_bmesh_normals_update(blender::Span nodes); /* pbvh_pixels.hh */ diff --git a/source/blender/editors/sculpt_paint/paint_hide.cc b/source/blender/editors/sculpt_paint/paint_hide.cc index a2e0f7b5054..d14973b9411 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.cc +++ b/source/blender/editors/sculpt_paint/paint_hide.cc @@ -11,6 +11,7 @@ #include "BLI_bitmap.h" #include "BLI_math_vector.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -43,6 +44,8 @@ /* For undo push. */ #include "sculpt_intern.hh" +using blender::Vector; + /* Return true if the element should be hidden/shown. */ static bool is_effected(PartialVisArea area, float planes[4][4], @@ -296,8 +299,7 @@ static void clip_planes_from_rect(bContext *C, * inside the clip_planes volume. If mode is outside, get all nodes * that lie at least partially outside the volume. If showing all, get * all nodes. */ -static void get_pbvh_nodes( - PBVH *pbvh, PBVHNode ***nodes, int *totnode, float clip_planes[4][4], PartialVisArea mode) +static Vector get_pbvh_nodes(PBVH *pbvh, float clip_planes[4][4], PartialVisArea mode) { BKE_pbvh_SearchCallback cb = nullptr; @@ -317,7 +319,7 @@ static void get_pbvh_nodes( PBVHFrustumPlanes frustum{}; frustum.planes = clip_planes; frustum.num_planes = 4; - BKE_pbvh_search_gather(pbvh, cb, &frustum, nodes, totnode); + return blender::bke::pbvh::search_gather(pbvh, cb, &frustum); } static int hide_show_exec(bContext *C, wmOperator *op) @@ -329,11 +331,9 @@ static int hide_show_exec(bContext *C, wmOperator *op) PartialVisAction action; PartialVisArea area; PBVH *pbvh; - PBVHNode **nodes; PBVHType pbvh_type; float clip_planes[4][4]; rcti rect; - int totnode; /* Read operator properties. */ action = PartialVisAction(RNA_enum_get(op->ptr, "action")); @@ -345,7 +345,7 @@ static int hide_show_exec(bContext *C, wmOperator *op) pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob); BLI_assert(BKE_object_sculpt_pbvh_get(ob) == pbvh); - get_pbvh_nodes(pbvh, &nodes, &totnode, clip_planes, area); + Vector nodes = get_pbvh_nodes(pbvh, clip_planes, area); pbvh_type = BKE_pbvh_type(pbvh); negate_m4(clip_planes); @@ -360,24 +360,20 @@ static int hide_show_exec(bContext *C, wmOperator *op) break; } - for (int i = 0; i < totnode; i++) { + for (PBVHNode *node : nodes) { switch (pbvh_type) { case PBVH_FACES: - partialvis_update_mesh(ob, pbvh, nodes[i], action, area, clip_planes); + partialvis_update_mesh(ob, pbvh, node, action, area, clip_planes); break; case PBVH_GRIDS: - partialvis_update_grids(depsgraph, ob, pbvh, nodes[i], action, area, clip_planes); + partialvis_update_grids(depsgraph, ob, pbvh, node, action, area, clip_planes); break; case PBVH_BMESH: - partialvis_update_bmesh(ob, pbvh, nodes[i], action, area, clip_planes); + partialvis_update_bmesh(ob, pbvh, node, action, area, clip_planes); break; } } - if (nodes) { - MEM_freeN(nodes); - } - /* End undo. */ SCULPT_undo_push_end(ob); diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 95576ba0027..2ccfa93c5b5 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -21,8 +21,10 @@ #include "BLI_math_matrix.h" #include "BLI_polyfill_2d.h" #include "BLI_rect.h" +#include "BLI_span.hh" #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "BKE_brush.h" #include "BKE_ccg.h" @@ -54,6 +56,9 @@ /* For undo push. */ #include "sculpt_intern.hh" +using blender::Span; +using blender::Vector; + static const EnumPropertyItem mode_items[] = { {PAINT_MASK_FLOOD_VALUE, "VALUE", @@ -86,7 +91,7 @@ static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float struct MaskTaskData { Object *ob; PBVH *pbvh; - PBVHNode **nodes; + Span nodes; bool multires; PaintMaskFloodMode mode; @@ -136,8 +141,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); PBVH *pbvh; - PBVHNode **nodes; - int totnode; + Vector nodes; bool multires; PaintMaskFloodMode mode = PaintMaskFloodMode(RNA_enum_get(op->ptr, "mode")); @@ -150,7 +154,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); SCULPT_undo_push_begin(ob, op); @@ -163,8 +167,8 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) data.value = value; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, mask_flood_fill_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, mask_flood_fill_task_cb, &settings); if (multires) { multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); @@ -174,10 +178,6 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) SCULPT_undo_push_end(ob); - if (nodes) { - MEM_freeN(nodes); - } - SCULPT_tag_update_overlays(C); return OPERATOR_FINISHED; @@ -288,8 +288,7 @@ struct SculptGestureContext { LineGestureData line; /* Task Callback Data. */ - PBVHNode **nodes; - int totnode; + Vector nodes; }; struct SculptGestureOperation { @@ -366,7 +365,7 @@ static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op) { - SculptGestureContext *sgcontext = MEM_cnew(__func__); + SculptGestureContext *sgcontext = MEM_new(__func__); sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LASSO; sculpt_gesture_context_init_common(C, op, sgcontext); @@ -417,7 +416,7 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperator *op) { - SculptGestureContext *sgcontext = MEM_cnew(__func__); + SculptGestureContext *sgcontext = MEM_new(__func__); sgcontext->shape_type = SCULPT_GESTURE_SHAPE_BOX; sculpt_gesture_context_init_common(C, op, sgcontext); @@ -493,7 +492,7 @@ static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgc static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperator *op) { - SculptGestureContext *sgcontext = MEM_cnew(__func__); + SculptGestureContext *sgcontext = MEM_new(__func__); sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LINE; sculpt_gesture_context_init_common(C, op, sgcontext); @@ -542,8 +541,7 @@ static void sculpt_gesture_context_free(SculptGestureContext *sgcontext) MEM_SAFE_FREE(sgcontext->lasso.mask_px); MEM_SAFE_FREE(sgcontext->gesture_points); MEM_SAFE_FREE(sgcontext->operation); - MEM_SAFE_FREE(sgcontext->nodes); - MEM_SAFE_FREE(sgcontext); + MEM_delete(sgcontext); } static void flip_plane(float out[4], const float in[4], const char symm) @@ -587,7 +585,8 @@ static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontex flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass); } -static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext) +static Vector sculpt_gesture_update_effected_nodes_by_line_plane( + SculptGestureContext *sgcontext) { SculptSession *ss = sgcontext->ss; float clip_planes[3][4]; @@ -599,11 +598,8 @@ static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureCont frustum.planes = clip_planes; frustum.num_planes = sgcontext->line.use_side_planes ? 3 : 1; - BKE_pbvh_search_gather(ss->pbvh, - BKE_pbvh_node_frustum_contain_AABB, - &frustum, - &sgcontext->nodes, - &sgcontext->totnode); + return sgcontext->nodes = blender::bke::pbvh::search_gather( + ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum); } static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureContext *sgcontext) @@ -617,11 +613,8 @@ static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureCon frustum.planes = clip_planes; frustum.num_planes = 4; - BKE_pbvh_search_gather(ss->pbvh, - BKE_pbvh_node_frustum_contain_AABB, - &frustum, - &sgcontext->nodes, - &sgcontext->totnode); + sgcontext->nodes = blender::bke::pbvh::search_gather( + ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum); } static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext) @@ -716,8 +709,6 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext, w sculpt_gesture_update_effected_nodes(sgcontext); operation->sculpt_gesture_apply_for_symmetry_pass(C, sgcontext); - - MEM_SAFE_FREE(sgcontext->nodes); } } @@ -773,9 +764,9 @@ static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->nodes.size()); BLI_task_parallel_range( - 0, sgcontext->totnode, sgcontext, face_set_gesture_apply_task_cb, &settings); + 0, sgcontext->nodes.size(), sgcontext, face_set_gesture_apply_task_cb, &settings); } static void sculpt_gesture_face_set_end(bContext * /*C*/, SculptGestureContext *sgcontext) @@ -862,8 +853,9 @@ static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode); - BLI_task_parallel_range(0, sgcontext->totnode, sgcontext, mask_gesture_apply_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->nodes.size()); + BLI_task_parallel_range( + 0, sgcontext->nodes.size(), sgcontext, mask_gesture_apply_task_cb, &settings); } static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext) @@ -1563,12 +1555,12 @@ static void sculpt_gesture_project_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->nodes.size()); switch (sgcontext->shape_type) { case SCULPT_GESTURE_SHAPE_LINE: BLI_task_parallel_range( - 0, sgcontext->totnode, sgcontext, project_line_gesture_apply_task_cb, &settings); + 0, sgcontext->nodes.size(), sgcontext, project_line_gesture_apply_task_cb, &settings); break; case SCULPT_GESTURE_SHAPE_LASSO: case SCULPT_GESTURE_SHAPE_BOX: diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 9b6e2465930..49e938af181 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -21,6 +21,7 @@ #include "BLI_string.h" #include "BLI_task.h" #include "BLI_task.hh" +#include "BLI_vector.hh" #include "DNA_brush_types.h" #include "DNA_mesh_types.h" @@ -2254,21 +2255,20 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void calculate_average_weight(SculptThreadedTaskData *data, - PBVHNode ** /*nodes*/, - int totnode) +static void calculate_average_weight(SculptThreadedTaskData *data, Span nodes) { - WPaintAverageAccum *accum = (WPaintAverageAccum *)MEM_mallocN(sizeof(*accum) * totnode, + WPaintAverageAccum *accum = (WPaintAverageAccum *)MEM_mallocN(sizeof(*accum) * nodes.size(), __func__); data->custom_data = accum; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, data, do_wpaint_brush_calc_average_weight_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range( + 0, nodes.size(), data, do_wpaint_brush_calc_average_weight_cb_ex, &settings); uint accum_len = 0; double accum_weight = 0.0; - for (int i = 0; i < totnode; i++) { + for (int i = 0; i < nodes.size(); i++) { accum_len += accum[i].len; accum_weight += accum[i].value; } @@ -2287,8 +2287,7 @@ static void wpaint_paint_leaves(bContext *C, WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me, - PBVHNode **nodes, - int totnode) + Span nodes) { Scene *scene = CTX_data_scene(C); const Brush *brush = ob->sculpt->cache->brush; @@ -2311,31 +2310,33 @@ static void wpaint_paint_leaves(bContext *C, /* NOTE: current mirroring code cannot be run in parallel */ TaskParallelSettings settings; const bool use_threading = !ME_USING_MIRROR_X_VERTEX_GROUPS(me); - BKE_pbvh_parallel_range_settings(&settings, use_threading, totnode); + BKE_pbvh_parallel_range_settings(&settings, use_threading, nodes.size()); switch ((eBrushWeightPaintTool)brush->weightpaint_tool) { case WPAINT_TOOL_AVERAGE: - calculate_average_weight(&data, nodes, totnode); - BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_draw_task_cb_ex, &settings); + calculate_average_weight(&data, nodes); + BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_draw_task_cb_ex, &settings); break; case WPAINT_TOOL_SMEAR: - BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_smear_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_smear_task_cb_ex, &settings); break; case WPAINT_TOOL_BLUR: - BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_blur_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_blur_task_cb_ex, &settings); break; case WPAINT_TOOL_DRAW: - BLI_task_parallel_range(0, totnode, &data, do_wpaint_brush_draw_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_wpaint_brush_draw_task_cb_ex, &settings); break; } } -static PBVHNode **vwpaint_pbvh_gather_generic( - Object *ob, VPaint *wp, Sculpt *sd, Brush *brush, int *r_totnode) +static Vector vwpaint_pbvh_gather_generic(Object *ob, + VPaint *wp, + Sculpt *sd, + Brush *brush) { SculptSession *ss = ob->sculpt; const bool use_normal = vwpaint_use_normal(wp); - PBVHNode **nodes = nullptr; + Vector nodes; /* Build a list of all nodes that are potentially within the brush's area of influence */ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { @@ -2345,10 +2346,10 @@ static PBVHNode **vwpaint_pbvh_gather_generic( data.radius_squared = ss->cache->radius_squared; data.original = true; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data); + if (use_normal) { - SCULPT_pbvh_calc_area_normal( - brush, ob, nodes, *r_totnode, true, ss->cache->sculpt_normal_symm); + SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, ss->cache->sculpt_normal_symm); } else { zero_v3(ss->cache->sculpt_normal_symm); @@ -2365,7 +2366,8 @@ static PBVHNode **vwpaint_pbvh_gather_generic( data.original = true; data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_circle_cb, &data); + if (use_normal) { copy_v3_v3(ss->cache->sculpt_normal_symm, ss->cache->view_normal); } @@ -2393,14 +2395,9 @@ static void wpaint_do_paint(bContext *C, ss->cache->radial_symmetry_pass = i; SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle); - int totnode; - PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, wp, sd, brush, &totnode); + Vector nodes = vwpaint_pbvh_gather_generic(ob, wp, sd, brush); - wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes, totnode); - - if (nodes) { - MEM_freeN(nodes); - } + wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes); } static void wpaint_do_radial_symmetry(bContext *C, @@ -2948,8 +2945,7 @@ static void do_vpaint_brush_blur_loops(bContext *C, VPaintData *vpd, Object *ob, Mesh *me, - PBVHNode **nodes, - int totnode, + Span nodes, Color *lcol) { using Blend = typename Traits::BlendType; @@ -2966,7 +2962,7 @@ static void do_vpaint_brush_blur_loops(bContext *C, const blender::VArray select_poly = me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); - blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { for (int n : range) { const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); const bool has_grids = (pbvh_type == PBVH_GRIDS); @@ -3092,8 +3088,7 @@ static void do_vpaint_brush_blur_verts(bContext *C, VPaintData *vpd, Object *ob, Mesh *me, - PBVHNode **nodes, - int totnode, + Span nodes, Color *lcol) { using Blend = typename Traits::BlendType; @@ -3110,7 +3105,7 @@ static void do_vpaint_brush_blur_verts(bContext *C, const blender::VArray select_poly = me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); - blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { for (int n : range) { const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); const bool has_grids = (pbvh_type == PBVH_GRIDS); @@ -3237,8 +3232,7 @@ static void do_vpaint_brush_smear(bContext *C, VPaintData *vpd, Object *ob, Mesh *me, - PBVHNode **nodes, - int totnode, + Span nodes, Color *lcol) { SculptSession *ss = ob->sculpt; @@ -3259,7 +3253,7 @@ static void do_vpaint_brush_smear(bContext *C, const blender::VArray select_poly = me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); - blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { for (int n : range) { float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; @@ -3417,8 +3411,7 @@ static void calculate_average_color(VPaintData *vpd, Mesh *me, const Brush *brush, Color *lcol, - PBVHNode **nodes, - int totnode) + Span nodes) { using Blend = typename Traits::BlendType; @@ -3426,8 +3419,8 @@ static void calculate_average_color(VPaintData *vpd, ".select_vert", ATTR_DOMAIN_POINT, false); VPaintAverageAccum *accum = (VPaintAverageAccum *)MEM_mallocN( - sizeof(*accum) * totnode, __func__); - blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + sizeof(*accum) * nodes.size(), __func__); + blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { for (int n : range) { SculptSession *ss = ob->sculpt; const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); @@ -3487,7 +3480,7 @@ static void calculate_average_color(VPaintData *vpd, Blend accum_value[3] = {0}; Color blend(0, 0, 0, 0); - for (int i = 0; i < totnode; i++) { + for (int i = 0; i < nodes.size(); i++) { accum_len += accum[i].len; accum_value[0] += accum[i].value[0]; accum_value[1] += accum[i].value[1]; @@ -3528,8 +3521,7 @@ static void vpaint_do_draw(bContext *C, VPaintData *vpd, Object *ob, Mesh *me, - PBVHNode **nodes, - int totnode, + Span nodes, Color *lcol) { SculptSession *ss = ob->sculpt; @@ -3545,7 +3537,7 @@ static void vpaint_do_draw(bContext *C, const blender::VArray select_poly = me->attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); - blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) { for (int n : range) { const bool has_grids = (pbvh_type == PBVH_GRIDS); const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; @@ -3671,15 +3663,14 @@ static void vpaint_do_blur(bContext *C, VPaintData *vpd, Object *ob, Mesh *me, - PBVHNode **nodes, - int totnode, + Span nodes, Color *lcol) { if constexpr (domain == ATTR_DOMAIN_POINT) { - do_vpaint_brush_blur_verts(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); + do_vpaint_brush_blur_verts(C, sd, vp, vpd, ob, me, nodes, lcol); } else { - do_vpaint_brush_blur_loops(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); + do_vpaint_brush_blur_loops(C, sd, vp, vpd, ob, me, nodes, lcol); } } @@ -3691,28 +3682,27 @@ static void vpaint_paint_leaves(bContext *C, Object *ob, Mesh *me, Color *lcol, - PBVHNode **nodes, - int totnode) + Span nodes) { - for (int i : IndexRange(totnode)) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COLOR); } const Brush *brush = ob->sculpt->cache->brush; switch ((eBrushVertexPaintTool)brush->vertexpaint_tool) { case VPAINT_TOOL_AVERAGE: - calculate_average_color(vpd, ob, me, brush, lcol, nodes, totnode); + calculate_average_color(vpd, ob, me, brush, lcol, nodes); break; case VPAINT_TOOL_DRAW: - vpaint_do_draw(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); + vpaint_do_draw(C, sd, vp, vpd, ob, me, nodes, lcol); break; case VPAINT_TOOL_BLUR: - vpaint_do_blur(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); + vpaint_do_blur(C, sd, vp, vpd, ob, me, nodes, lcol); break; case VPAINT_TOOL_SMEAR: - do_vpaint_brush_smear(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); + do_vpaint_brush_smear(C, sd, vp, vpd, ob, me, nodes, lcol); break; default: break; @@ -3736,8 +3726,7 @@ static void vpaint_do_paint(bContext *C, ss->cache->radial_symmetry_pass = i; SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle); - int totnode; - PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush, &totnode); + Vector nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush); bke::GSpanAttributeWriter attribute = me->attributes_for_write().lookup_for_write_span( me->active_color_attribute); @@ -3746,12 +3735,9 @@ static void vpaint_do_paint(bContext *C, Color *color_data = static_cast(attribute.span.data()); /* Paint those leaves. */ - vpaint_paint_leaves(C, sd, vp, vpd, ob, me, color_data, nodes, totnode); + vpaint_paint_leaves(C, sd, vp, vpd, ob, me, color_data, nodes); attribute.finish(); - if (nodes) { - MEM_freeN(nodes); - } } template diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc index 852fa700db6..37423650187 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc @@ -300,18 +300,17 @@ static void transform_active_color(bContext *C, wmOperator *op, const TransformF CTX_data_ensure_evaluated_depsgraph(C), obact, true, false, true); SCULPT_undo_push_begin(obact, op); - PBVHNode **nodes; - int nodes_num; - BKE_pbvh_search_gather(obact->sculpt->pbvh, nullptr, nullptr, &nodes, &nodes_num); - for (int i : IndexRange(nodes_num)) { - SCULPT_undo_push_node(obact, nodes[i], SCULPT_UNDO_COLOR); + Vector nodes = blender::bke::pbvh::search_gather( + obact->sculpt->pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(obact, node, SCULPT_UNDO_COLOR); } transform_active_color_data(*BKE_mesh_from_object(obact), transform_fn); - for (int i : IndexRange(nodes_num)) { - BKE_pbvh_node_mark_update_color(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update_color(node); } SCULPT_undo_push_end(obact); diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index aac82868fcb..9b4ec4c28b1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -79,6 +79,7 @@ using blender::float3; using blender::MutableSpan; using blender::Set; +using blender::Span; using blender::Vector; static float sculpt_calc_radius(ViewContext *vc, @@ -1101,16 +1102,16 @@ PBVHVertRef SCULPT_nearest_vertex_get( Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = nullptr; - int totnode; + Vector nodes; + SculptSearchSphereData data{}; data.sd = sd; data.radius_squared = max_distance * max_distance; data.original = use_original; data.center = co; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); - if (totnode == 0) { + nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data); + if (nodes.is_empty()) { return BKE_pbvh_make_vref(PBVH_REF_NONE); } @@ -1126,13 +1127,11 @@ PBVHVertRef SCULPT_nearest_vertex_get( nvtd.nearest_vertex_distance_squared = FLT_MAX; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); settings.func_reduce = nearest_vertex_get_reduce; settings.userdata_chunk = &nvtd; settings.userdata_chunk_size = sizeof(NearestVertexTLSData); - BLI_task_parallel_range(0, totnode, &task_data, do_nearest_vertex_get_task_cb, &settings); - - MEM_SAFE_FREE(nodes); + BLI_task_parallel_range(0, nodes.size(), &task_data, do_nearest_vertex_get_task_cb, &settings); return nvtd.nearest_vertex; } @@ -1619,10 +1618,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob) SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - PBVHNode **nodes; - int totnode; - - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); /** * Disable multi-threading when dynamic-topology is enabled. Otherwise, @@ -1636,12 +1632,10 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob) data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, totnode); - BLI_task_parallel_range(0, totnode, &data, paint_mesh_restore_co_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, paint_mesh_restore_co_task_cb, &settings); BKE_pbvh_node_color_buffer_free(ss->pbvh); - - MEM_SAFE_FREE(nodes); } /*** BVH Tree ***/ @@ -2249,8 +2243,7 @@ static void calc_area_normal_and_center_reduce(const void *__restrict /*userdata add_v2_v2_int(join->count_co, anctd->count_co); } -void SCULPT_calc_area_center( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3]) +void SCULPT_calc_area_center(Sculpt *sd, Object *ob, Span nodes, float r_area_co[3]) { const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; @@ -2263,18 +2256,17 @@ void SCULPT_calc_area_center( data.ob = ob; data.brush = brush; data.nodes = nodes; - data.totnode = totnode; data.has_bm_orco = has_bm_orco; data.use_area_cos = true; AreaNormalCenterTLSData anctd = {{{0}}}; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); settings.func_reduce = calc_area_normal_and_center_reduce; settings.userdata_chunk = &anctd; settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData); - BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, calc_area_normal_and_center_task_cb, &settings); /* For flatten center. */ for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) { @@ -2297,19 +2289,14 @@ void SCULPT_calc_area_center( } } -void SCULPT_calc_area_normal( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3]) +void SCULPT_calc_area_normal(Sculpt *sd, Object *ob, Span nodes, float r_area_no[3]) { const Brush *brush = BKE_paint_brush(&sd->paint); - SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, r_area_no); + SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, r_area_no); } -bool SCULPT_pbvh_calc_area_normal(const Brush *brush, - Object *ob, - PBVHNode **nodes, - int totnode, - bool use_threading, - float r_area_no[3]) +bool SCULPT_pbvh_calc_area_normal( + const Brush *brush, Object *ob, Span nodes, bool use_threading, float r_area_no[3]) { SculptSession *ss = ob->sculpt; const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush); @@ -2320,7 +2307,6 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush, data.ob = ob; data.brush = brush; data.nodes = nodes; - data.totnode = totnode; data.has_bm_orco = has_bm_orco; data.use_area_nos = true; data.any_vertex_sampled = false; @@ -2328,11 +2314,11 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush, AreaNormalCenterTLSData anctd = {{{0}}}; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, use_threading, totnode); + BKE_pbvh_parallel_range_settings(&settings, use_threading, nodes.size()); settings.func_reduce = calc_area_normal_and_center_reduce; settings.userdata_chunk = &anctd; settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData); - BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, calc_area_normal_and_center_task_cb, &settings); /* For area normal. */ for (int i = 0; i < ARRAY_SIZE(anctd.area_nos); i++) { @@ -2345,7 +2331,7 @@ bool SCULPT_pbvh_calc_area_normal(const Brush *brush, } void SCULPT_calc_area_normal_and_center( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]) + Sculpt *sd, Object *ob, Span nodes, float r_area_no[3], float r_area_co[3]) { const Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; @@ -2358,7 +2344,6 @@ void SCULPT_calc_area_normal_and_center( data.ob = ob; data.brush = brush; data.nodes = nodes; - data.totnode = totnode; data.has_bm_orco = has_bm_orco; data.use_area_cos = true; data.use_area_nos = true; @@ -2366,11 +2351,11 @@ void SCULPT_calc_area_normal_and_center( AreaNormalCenterTLSData anctd = {{{0}}}; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); settings.func_reduce = calc_area_normal_and_center_reduce; settings.userdata_chunk = &anctd; settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData); - BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, calc_area_normal_and_center_task_cb, &settings); /* For flatten center. */ for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) { @@ -2850,13 +2835,11 @@ void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3]) } } -static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob, - Sculpt *sd, - bool use_original, - int *r_totnode) +static Vector sculpt_pbvh_gather_cursor_update(Object *ob, + Sculpt *sd, + bool use_original) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = nullptr; SculptSearchSphereData data{}; data.ss = ss; data.sd = sd; @@ -2864,20 +2847,19 @@ static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob, data.original = use_original; data.ignore_fully_ineffective = false; data.center = nullptr; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); - return nodes; + + return blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data); } -static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob, - Sculpt *sd, - const Brush *brush, - bool use_original, - float radius_scale, - int *r_totnode, - PBVHNodeFlags flag) +static Vector sculpt_pbvh_gather_generic_intern(Object *ob, + Sculpt *sd, + const Brush *brush, + bool use_original, + float radius_scale, + PBVHNodeFlags flag) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = nullptr; + Vector nodes; PBVHNodeFlags leaf_flag = PBVH_Leaf; if (flag & PBVH_TexLeaf) { @@ -2894,8 +2876,7 @@ static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob, data.original = use_original; data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; data.center = nullptr; - BKE_pbvh_search_gather_ex( - ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode, leaf_flag); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, leaf_flag); } else { DistRayAABB_Precalc dist_ray_to_aabb_precalc; @@ -2909,37 +2890,27 @@ static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob, data.original = use_original; data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc; data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; - BKE_pbvh_search_gather_ex( - ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode, leaf_flag); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, leaf_flag); } + return nodes; } -static PBVHNode **sculpt_pbvh_gather_generic(Object *ob, - Sculpt *sd, - const Brush *brush, - bool use_original, - float radius_scale, - int *r_totnode) +static Vector sculpt_pbvh_gather_generic( + Object *ob, Sculpt *sd, const Brush *brush, bool use_original, float radius_scale) { - return sculpt_pbvh_gather_generic_intern( - ob, sd, brush, use_original, radius_scale, r_totnode, PBVH_Leaf); + return sculpt_pbvh_gather_generic_intern(ob, sd, brush, use_original, radius_scale, PBVH_Leaf); } -static PBVHNode **sculpt_pbvh_gather_texpaint(Object *ob, - Sculpt *sd, - const Brush *brush, - bool use_original, - float radius_scale, - int *r_totnode) +static Vector sculpt_pbvh_gather_texpaint( + Object *ob, Sculpt *sd, const Brush *brush, bool use_original, float radius_scale) { return sculpt_pbvh_gather_generic_intern( - ob, sd, brush, use_original, radius_scale, r_totnode, PBVH_TexLeaf); + ob, sd, brush, use_original, radius_scale, PBVH_TexLeaf); } /* Calculate primary direction of movement for many brushes. */ -static void calc_sculpt_normal( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3]) +static void calc_sculpt_normal(Sculpt *sd, Object *ob, Span nodes, float r_area_no[3]) { const Brush *brush = BKE_paint_brush(&sd->paint); const SculptSession *ss = ob->sculpt; @@ -2962,7 +2933,7 @@ static void calc_sculpt_normal( break; case SCULPT_DISP_DIR_AREA: - SCULPT_calc_area_normal(sd, ob, nodes, totnode, r_area_no); + SCULPT_calc_area_normal(sd, ob, nodes, r_area_no); break; default: @@ -2970,7 +2941,7 @@ static void calc_sculpt_normal( } } -static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +static void update_sculpt_normal(Sculpt *sd, Object *ob, Span nodes) { const Brush *brush = BKE_paint_brush(&sd->paint); StrokeCache *cache = ob->sculpt->cache; @@ -2983,7 +2954,7 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int t if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 && (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(cache) || update_normal)) { - calc_sculpt_normal(sd, ob, nodes, totnode, cache->sculpt_normal); + calc_sculpt_normal(sd, ob, nodes, cache->sculpt_normal); if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { project_plane_v3_v3v3(cache->sculpt_normal, cache->sculpt_normal, cache->view_normal); normalize_v3(cache->sculpt_normal); @@ -3222,7 +3193,7 @@ void SCULPT_flip_quat_by_symm_area(float quat[4], } void SCULPT_calc_brush_plane( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]) + Sculpt *sd, Object *ob, Span nodes, float r_area_no[3], float r_area_co[3]) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -3251,7 +3222,7 @@ void SCULPT_calc_brush_plane( break; case SCULPT_DISP_DIR_AREA: - SCULPT_calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co); + SCULPT_calc_area_normal_and_center(sd, ob, nodes, r_area_no, r_area_co); if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal); normalize_v3(r_area_no); @@ -3265,7 +3236,7 @@ void SCULPT_calc_brush_plane( /* For flatten center. */ /* Flatten center has not been calculated yet if we are not using the area normal. */ if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) { - SCULPT_calc_area_center(sd, ob, nodes, totnode, r_area_co); + SCULPT_calc_area_center(sd, ob, nodes, r_area_co); } /* For area normal. */ @@ -3384,7 +3355,7 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength) +static void do_gravity(Sculpt *sd, Object *ob, Span nodes, float bstrength) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -3407,8 +3378,8 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl data.offset = offset; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_gravity_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_gravity_task_cb_ex, &settings); } /** \} */ @@ -3463,16 +3434,14 @@ static void sculpt_topology_update(Sculpt *sd, { SculptSession *ss = ob->sculpt; - int n, totnode; /* Build a list of all nodes that are potentially within the brush's area of influence. */ const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : ss->cache->original; const float radius_scale = 1.25f; - PBVHNode **nodes = sculpt_pbvh_gather_generic( - ob, sd, brush, use_original, radius_scale, &totnode); + Vector nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale); /* Only act if some verts are inside the brush area. */ - if (totnode == 0) { + if (nodes.is_empty()) { return; } @@ -3493,16 +3462,14 @@ static void sculpt_topology_update(Sculpt *sd, } } - for (n = 0; n < totnode; n++) { - SCULPT_undo_push_node(ob, - nodes[n], - brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK : - SCULPT_UNDO_COORDS); - BKE_pbvh_node_mark_update(nodes[n]); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node( + ob, node, brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS); + BKE_pbvh_node_mark_update(node); if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) { - BKE_pbvh_node_mark_topology_update(nodes[n]); - BKE_pbvh_bmesh_node_save_orig(ss->bm, ss->bm_log, nodes[n], false); + BKE_pbvh_node_mark_topology_update(node); + BKE_pbvh_bmesh_node_save_orig(ss->bm, ss->bm_log, node, false); } } @@ -3516,8 +3483,6 @@ static void sculpt_topology_update(Sculpt *sd, (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE)); } - MEM_SAFE_FREE(nodes); - /* Update average stroke position. */ copy_v3_v3(location, ss->cache->true_location); mul_m4_v3(ob->object_to_world, location); @@ -3568,8 +3533,7 @@ static void do_brush_action(Sculpt *sd, PaintModeSettings *paint_mode_settings) { SculptSession *ss = ob->sculpt; - int totnode, texnodes_num = 0; - PBVHNode **nodes, **texnodes = nullptr; + Vector nodes, texnodes; /* Check for unsupported features. */ PBVHType type = BKE_pbvh_type(ss->pbvh); @@ -3589,9 +3553,9 @@ static void do_brush_action(Sculpt *sd, if (sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob)) { sculpt_pbvh_update_pixels(paint_mode_settings, ss, ob); - texnodes = sculpt_pbvh_gather_texpaint(ob, sd, brush, use_original, 1.0f, &texnodes_num); + texnodes = sculpt_pbvh_gather_texpaint(ob, sd, brush, use_original, 1.0f); - if (!texnodes_num) { + if (texnodes.is_empty()) { return; } } @@ -3600,10 +3564,10 @@ static void do_brush_action(Sculpt *sd, if (SCULPT_tool_needs_all_pbvh_nodes(brush)) { /* These brushes need to update all nodes as they are not constrained by the brush radius */ - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { - nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush, &totnode); + nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush); } else { float radius_scale = 1.0f; @@ -3618,7 +3582,7 @@ static void do_brush_action(Sculpt *sd, if (brush->sculpt_tool == SCULPT_TOOL_DRAW && brush->flag & BRUSH_ORIGINAL_NORMAL) { radius_scale = 2.0f; } - nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode); + nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale); } /* Draw Face Sets in draw mode makes a single undo push, in alt-smooth mode deforms the @@ -3639,7 +3603,7 @@ static void do_brush_action(Sculpt *sd, /* For anchored brushes with spherical falloff, we start off with zero radius, thus we have no * PBVH nodes on the first brush step. */ - if (totnode || + if (!nodes.is_empty() || ((brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) && (brush->flag & BRUSH_ANCHORED))) { if (SCULPT_stroke_is_first_brush_step(ss->cache)) { /* Initialize auto-masking cache. */ @@ -3659,8 +3623,7 @@ static void do_brush_action(Sculpt *sd, } /* Only act if some verts are inside the brush area. */ - if (totnode == 0) { - MEM_SAFE_FREE(texnodes); + if (nodes.is_empty()) { return; } float location[3]; @@ -3673,12 +3636,12 @@ static void do_brush_action(Sculpt *sd, task_data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &task_data, do_brush_action_task_cb, &settings); } if (sculpt_brush_needs_normal(ss, sd, brush)) { - update_sculpt_normal(sd, ob, nodes, totnode); + update_sculpt_normal(sd, ob, nodes); } update_brush_local_mat(sd, ob); @@ -3695,7 +3658,7 @@ static void do_brush_action(Sculpt *sd, } SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim); SCULPT_cloth_brush_ensure_nodes_constraints( - sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX); + sd, ob, nodes, ss->cache->cloth_sim, ss->cache->location, FLT_MAX); } bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN; @@ -3703,128 +3666,127 @@ static void do_brush_action(Sculpt *sd, /* Apply one type of brush action. */ switch (brush->sculpt_tool) { case SCULPT_TOOL_DRAW: - SCULPT_do_draw_brush(sd, ob, nodes, totnode); + SCULPT_do_draw_brush(sd, ob, nodes); break; case SCULPT_TOOL_SMOOTH: if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) { - SCULPT_do_smooth_brush(sd, ob, nodes, totnode); + SCULPT_do_smooth_brush(sd, ob, nodes); } else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) { - SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode); + SCULPT_do_surface_smooth_brush(sd, ob, nodes); } break; case SCULPT_TOOL_CREASE: - SCULPT_do_crease_brush(sd, ob, nodes, totnode); + SCULPT_do_crease_brush(sd, ob, nodes); break; case SCULPT_TOOL_BLOB: - SCULPT_do_crease_brush(sd, ob, nodes, totnode); + SCULPT_do_crease_brush(sd, ob, nodes); break; case SCULPT_TOOL_PINCH: - SCULPT_do_pinch_brush(sd, ob, nodes, totnode); + SCULPT_do_pinch_brush(sd, ob, nodes); break; case SCULPT_TOOL_INFLATE: - SCULPT_do_inflate_brush(sd, ob, nodes, totnode); + SCULPT_do_inflate_brush(sd, ob, nodes); break; case SCULPT_TOOL_GRAB: - SCULPT_do_grab_brush(sd, ob, nodes, totnode); + SCULPT_do_grab_brush(sd, ob, nodes); break; case SCULPT_TOOL_ROTATE: - SCULPT_do_rotate_brush(sd, ob, nodes, totnode); + SCULPT_do_rotate_brush(sd, ob, nodes); break; case SCULPT_TOOL_SNAKE_HOOK: - SCULPT_do_snake_hook_brush(sd, ob, nodes, totnode); + SCULPT_do_snake_hook_brush(sd, ob, nodes); break; case SCULPT_TOOL_NUDGE: - SCULPT_do_nudge_brush(sd, ob, nodes, totnode); + SCULPT_do_nudge_brush(sd, ob, nodes); break; case SCULPT_TOOL_THUMB: - SCULPT_do_thumb_brush(sd, ob, nodes, totnode); + SCULPT_do_thumb_brush(sd, ob, nodes); break; case SCULPT_TOOL_LAYER: - SCULPT_do_layer_brush(sd, ob, nodes, totnode); + SCULPT_do_layer_brush(sd, ob, nodes); break; case SCULPT_TOOL_FLATTEN: - SCULPT_do_flatten_brush(sd, ob, nodes, totnode); + SCULPT_do_flatten_brush(sd, ob, nodes); break; case SCULPT_TOOL_CLAY: - SCULPT_do_clay_brush(sd, ob, nodes, totnode); + SCULPT_do_clay_brush(sd, ob, nodes); break; case SCULPT_TOOL_CLAY_STRIPS: - SCULPT_do_clay_strips_brush(sd, ob, nodes, totnode); + SCULPT_do_clay_strips_brush(sd, ob, nodes); break; case SCULPT_TOOL_MULTIPLANE_SCRAPE: - SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode); + SCULPT_do_multiplane_scrape_brush(sd, ob, nodes); break; case SCULPT_TOOL_CLAY_THUMB: - SCULPT_do_clay_thumb_brush(sd, ob, nodes, totnode); + SCULPT_do_clay_thumb_brush(sd, ob, nodes); break; case SCULPT_TOOL_FILL: if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) { - SCULPT_do_scrape_brush(sd, ob, nodes, totnode); + SCULPT_do_scrape_brush(sd, ob, nodes); } else { - SCULPT_do_fill_brush(sd, ob, nodes, totnode); + SCULPT_do_fill_brush(sd, ob, nodes); } break; case SCULPT_TOOL_SCRAPE: if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) { - SCULPT_do_fill_brush(sd, ob, nodes, totnode); + SCULPT_do_fill_brush(sd, ob, nodes); } else { - SCULPT_do_scrape_brush(sd, ob, nodes, totnode); + SCULPT_do_scrape_brush(sd, ob, nodes); } break; case SCULPT_TOOL_MASK: - SCULPT_do_mask_brush(sd, ob, nodes, totnode); + SCULPT_do_mask_brush(sd, ob, nodes); break; case SCULPT_TOOL_POSE: - SCULPT_do_pose_brush(sd, ob, nodes, totnode); + SCULPT_do_pose_brush(sd, ob, nodes); break; case SCULPT_TOOL_DRAW_SHARP: - SCULPT_do_draw_sharp_brush(sd, ob, nodes, totnode); + SCULPT_do_draw_sharp_brush(sd, ob, nodes); break; case SCULPT_TOOL_ELASTIC_DEFORM: - SCULPT_do_elastic_deform_brush(sd, ob, nodes, totnode); + SCULPT_do_elastic_deform_brush(sd, ob, nodes); break; case SCULPT_TOOL_SLIDE_RELAX: - SCULPT_do_slide_relax_brush(sd, ob, nodes, totnode); + SCULPT_do_slide_relax_brush(sd, ob, nodes); break; case SCULPT_TOOL_BOUNDARY: - SCULPT_do_boundary_brush(sd, ob, nodes, totnode); + SCULPT_do_boundary_brush(sd, ob, nodes); break; case SCULPT_TOOL_CLOTH: - SCULPT_do_cloth_brush(sd, ob, nodes, totnode); + SCULPT_do_cloth_brush(sd, ob, nodes); break; case SCULPT_TOOL_DRAW_FACE_SETS: - SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode); + SCULPT_do_draw_face_sets_brush(sd, ob, nodes); break; case SCULPT_TOOL_DISPLACEMENT_ERASER: - SCULPT_do_displacement_eraser_brush(sd, ob, nodes, totnode); + SCULPT_do_displacement_eraser_brush(sd, ob, nodes); break; case SCULPT_TOOL_DISPLACEMENT_SMEAR: - SCULPT_do_displacement_smear_brush(sd, ob, nodes, totnode); + SCULPT_do_displacement_smear_brush(sd, ob, nodes); break; case SCULPT_TOOL_PAINT: - SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, totnode, texnodes, texnodes_num); + SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, texnodes); break; case SCULPT_TOOL_SMEAR: - SCULPT_do_smear_brush(sd, ob, nodes, totnode); + SCULPT_do_smear_brush(sd, ob, nodes); break; } if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) && brush->autosmooth_factor > 0) { if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) { - SCULPT_smooth( - sd, ob, nodes, totnode, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false); + SCULPT_smooth(sd, ob, nodes, brush->autosmooth_factor * (1.0f - ss->cache->pressure), false); } else { - SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false); + SCULPT_smooth(sd, ob, nodes, brush->autosmooth_factor, false); } } if (sculpt_brush_use_topology_rake(ss, brush)) { - SCULPT_bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor); + SCULPT_bmesh_topology_rake(sd, ob, nodes, brush->topology_rake_factor); } if (!SCULPT_tool_can_reuse_automask(brush->sculpt_tool) || @@ -3838,19 +3800,16 @@ static void do_brush_action(Sculpt *sd, SCULPT_TOOL_CLOTH, SCULPT_TOOL_DRAW_FACE_SETS, SCULPT_TOOL_BOUNDARY)) { - do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); + do_gravity(sd, ob, nodes, sd->gravity_factor); } if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) { - SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode); - SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); + SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes); + SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes); } } - MEM_SAFE_FREE(nodes); - MEM_SAFE_FREE(texnodes); - /* Update average stroke position. */ copy_v3_v3(location, ss->cache->true_location); mul_m4_v3(ob->object_to_world, location); @@ -3951,17 +3910,13 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob) SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE); - int totnode; - PBVHNode **nodes; - BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::gather_proxies(ss->pbvh); - threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) { + threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) { for (const int i : range) { sculpt_combine_proxies_node(*ob, *sd, use_orco, *nodes[i]); } }); - - MEM_SAFE_FREE(nodes); } void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob) @@ -3969,17 +3924,13 @@ void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob) using namespace blender; SculptSession *ss = ob->sculpt; - int totnode; - PBVHNode **nodes; - BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::gather_proxies(ss->pbvh); - threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) { + threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) { for (const int i : range) { sculpt_combine_proxies_node(*ob, *sd, false, *nodes[i]); } }); - - MEM_SAFE_FREE(nodes); } /** @@ -4019,9 +3970,8 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used) /* This brushes aren't using proxies, so sculpt_combine_proxies() wouldn't propagate needed * deformation to original base. */ - int totnode; Mesh *me = (Mesh *)ob->data; - PBVHNode **nodes; + Vector nodes; float(*vertCos)[3] = nullptr; if (ss->shapekey_active) { @@ -4033,11 +3983,11 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used) memcpy(vertCos, ss->orig_cos, sizeof(*vertCos) * me->totvert); } - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); MutableSpan positions = me->vert_positions_for_write(); - threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) { + threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) { for (const int i : range) { PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) { @@ -4058,8 +4008,6 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used) SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos); MEM_freeN(vertCos); } - - MEM_SAFE_FREE(nodes); } else if (ss->shapekey_active) { sculpt_update_keyblock(ob); @@ -5162,7 +5110,6 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, float ray_start[3], ray_end[3], ray_normal[3], depth, face_normal[3], sampled_normal[3], mat[3][3]; float viewDir[3] = {0.0f, 0.0f, 1.0f}; - int totnode; bool original = false; ED_view3d_viewcontext_init(C, &vc, depsgraph); @@ -5254,17 +5201,16 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, } ss->cursor_radius = radius; - PBVHNode **nodes = sculpt_pbvh_gather_cursor_update(ob, sd, original, &totnode); + Vector nodes = sculpt_pbvh_gather_cursor_update(ob, sd, original); /* In case there are no nodes under the cursor, return the face normal. */ - if (!totnode) { - MEM_SAFE_FREE(nodes); + if (nodes.is_empty()) { copy_v3_v3(out->normal, srd.face_normal); return true; } /* Calculate the sampled normal. */ - if (SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, sampled_normal)) { + if (SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, sampled_normal)) { copy_v3_v3(out->normal, sampled_normal); copy_v3_v3(ss->cursor_sampled_normal, sampled_normal); } @@ -5272,7 +5218,6 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, /* Use face normal when there are no vertices to sample inside the cursor radius. */ copy_v3_v3(out->normal, srd.face_normal); } - MEM_SAFE_FREE(nodes); return true; } @@ -6138,8 +6083,8 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, float max_distance) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes = nullptr; - int totnode; + Vector nodes; + SculptSearchSphereData data{}; data.ss = ss; data.sd = sd; @@ -6147,9 +6092,9 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, data.original = false; data.center = SCULPT_vertex_co_get(ss, vertex); - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data); - if (totnode == 0) { + if (nodes.is_empty()) { return BKE_pbvh_make_vref(PBVH_REF_NONE); } @@ -6167,13 +6112,11 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, nvtd.current_topology_id = SCULPT_vertex_island_get(ss, vertex); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); settings.func_reduce = fake_neighbor_search_reduce; settings.userdata_chunk = &nvtd; settings.userdata_chunk_size = sizeof(NearestVertexFakeNeighborTLSData); - BLI_task_parallel_range(0, totnode, &task_data, do_fake_neighbor_search_task_cb, &settings); - - MEM_SAFE_FREE(nodes); + BLI_task_parallel_range(0, nodes.size(), &task_data, do_fake_neighbor_search_task_cb, &settings); return nvtd.nearest_vertex; } diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.cc b/source/blender/editors/sculpt_paint/sculpt_boundary.cc index e1a4a8efc0c..964633d988d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.cc +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.cc @@ -973,7 +973,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1031,26 +1031,32 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); switch (brush->boundary_deform_type) { case BRUSH_BOUNDARY_DEFORM_BEND: - BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_bend_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_boundary_brush_bend_task_cb_ex, &settings); break; case BRUSH_BOUNDARY_DEFORM_EXPAND: - BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_slide_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_boundary_brush_slide_task_cb_ex, &settings); break; case BRUSH_BOUNDARY_DEFORM_INFLATE: - BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_inflate_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_boundary_brush_inflate_task_cb_ex, &settings); break; case BRUSH_BOUNDARY_DEFORM_GRAB: - BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_grab_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_boundary_brush_grab_task_cb_ex, &settings); break; case BRUSH_BOUNDARY_DEFORM_TWIST: - BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_twist_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_boundary_brush_twist_task_cb_ex, &settings); break; case BRUSH_BOUNDARY_DEFORM_SMOOTH: - BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_smooth_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_boundary_brush_smooth_task_cb_ex, &settings); break; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.cc b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc index 9e6ce8131ef..1185dd7441d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.cc +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.cc @@ -13,6 +13,7 @@ #include "BLI_math.h" #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BLI_span.hh" #include "DNA_brush_types.h" #include "DNA_customdata_types.h" @@ -39,6 +40,8 @@ #include #include +using blender::Span; + /* -------------------------------------------------------------------- */ /** \name SculptProjectVector * @@ -86,7 +89,7 @@ static void sculpt_project_v3(const SculptProjectVector *spvc, const float vec[3 } static void calc_sculpt_plane( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]) + Sculpt *sd, Object *ob, Span nodes, float r_area_no[3], float r_area_co[3]) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -112,7 +115,7 @@ static void calc_sculpt_plane( break; case SCULPT_DISP_DIR_AREA: - SCULPT_calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co); + SCULPT_calc_area_normal_and_center(sd, ob, nodes, r_area_no, r_area_co); if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal); normalize_v3(r_area_no); @@ -126,7 +129,7 @@ static void calc_sculpt_plane( /* For flatten center. */ /* Flatten center has not been calculated yet if we are not using the area normal. */ if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) { - SCULPT_calc_area_center(sd, ob, nodes, totnode, r_area_co); + SCULPT_calc_area_center(sd, ob, nodes, r_area_co); } /* For area normal. */ @@ -302,7 +305,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -329,8 +332,8 @@ void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) data.offset = offset; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_draw_brush_task_cb_ex, &settings); } /** \} */ @@ -406,7 +409,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -421,7 +424,7 @@ void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float temp[3]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co); SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor); @@ -440,8 +443,8 @@ void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) data.area_co = area_co; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_fill_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_fill_brush_task_cb_ex, &settings); } static void do_scrape_brush_task_cb_ex(void *__restrict userdata, @@ -510,7 +513,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -525,7 +528,7 @@ void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod float temp[3]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co); SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor); @@ -544,8 +547,8 @@ void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod data.area_co = area_co; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_scrape_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_scrape_brush_task_cb_ex, &settings); } /** \} */ @@ -643,7 +646,7 @@ float SCULPT_clay_thumb_get_stabilized_pressure(StrokeCache *cache) return final_pressure / SCULPT_CLAY_STABILIZER_LEN; } -void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -662,10 +665,10 @@ void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to float scale[4][4]; float tmat[4][4]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no_sp, area_co); if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) { - SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no); + SCULPT_calc_area_normal(sd, ob, nodes, area_no); } else { copy_v3_v3(area_no, area_no_sp); @@ -724,8 +727,8 @@ void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to data.clay_strength = clay_strength; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_clay_thumb_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_clay_thumb_brush_task_cb_ex, &settings); } /** \} */ @@ -796,7 +799,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -810,7 +813,7 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno float displace; float temp[3]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co); SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor); @@ -829,8 +832,8 @@ void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno data.area_co = area_co; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_flatten_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_flatten_brush_task_cb_ex, &settings); } /** \} */ @@ -958,7 +961,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -974,26 +977,26 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) float area_co[3]; float temp[3]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co); SculptThreadedTaskData sample_data{}; sample_data.sd = nullptr; sample_data.ob = ob; sample_data.brush = brush; sample_data.nodes = nodes; - sample_data.totnode = totnode; sample_data.area_no = area_no; sample_data.area_co = ss->cache->location; ClaySampleData csd = {{0}}; TaskParallelSettings sample_settings; - BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode); + BKE_pbvh_parallel_range_settings(&sample_settings, true, nodes.size()); sample_settings.func_reduce = calc_clay_surface_reduce; sample_settings.userdata_chunk = &csd; sample_settings.userdata_chunk_size = sizeof(ClaySampleData); - BLI_task_parallel_range(0, totnode, &sample_data, calc_clay_surface_task_cb, &sample_settings); + BLI_task_parallel_range( + 0, nodes.size(), &sample_data, calc_clay_surface_task_cb, &sample_settings); float d_offset = (csd.plane_dist[0] + csd.plane_dist[1]); d_offset = min_ff(radius, d_offset); @@ -1018,8 +1021,8 @@ void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) data.area_co = area_co; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_clay_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_clay_brush_task_cb_ex, &settings); } static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, @@ -1090,7 +1093,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1112,11 +1115,11 @@ void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t float scale[4][4]; float tmat[4][4]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no_sp, area_co); SCULPT_tilt_apply_to_normal(area_no_sp, ss->cache, brush->tilt_strength_factor); if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) { - SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no); + SCULPT_calc_area_normal(sd, ob, nodes, area_no); } else { copy_v3_v3(area_no, area_no_sp); @@ -1178,8 +1181,8 @@ void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t data.mat = mat; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_clay_strips_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_clay_strips_brush_task_cb_ex, &settings); } static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, @@ -1298,7 +1301,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1331,8 +1334,8 @@ void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to data.grab_delta = grab_delta; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_snake_hook_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_snake_hook_brush_task_cb_ex, &settings); } static void do_thumb_brush_task_cb_ex(void *__restrict userdata, @@ -1390,7 +1393,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1410,8 +1413,8 @@ void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode data.cono = cono; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_thumb_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_thumb_brush_task_cb_ex, &settings); } static void do_rotate_brush_task_cb_ex(void *__restrict userdata, @@ -1475,7 +1478,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1491,8 +1494,8 @@ void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod data.angle = angle; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_rotate_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_rotate_brush_task_cb_ex, &settings); } static void do_layer_brush_task_cb_ex(void *__restrict userdata, @@ -1598,7 +1601,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1615,8 +1618,8 @@ void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_layer_brush_task_cb_ex, &settings); } static void do_inflate_brush_task_cb_ex(void *__restrict userdata, @@ -1677,7 +1680,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, Span nodes) { Brush *brush = BKE_paint_brush(&sd->paint); @@ -1688,8 +1691,8 @@ void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_inflate_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_inflate_brush_task_cb_ex, &settings); } static void do_nudge_brush_task_cb_ex(void *__restrict userdata, @@ -1742,7 +1745,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1762,8 +1765,8 @@ void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode data.cono = cono; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_nudge_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_nudge_brush_task_cb_ex, &settings); } /** \} */ @@ -1842,7 +1845,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; const Scene *scene = ss->cache->vc->scene; @@ -1890,8 +1893,8 @@ void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod data.flippedbstrength = flippedbstrength; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_crease_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_crease_brush_task_cb_ex, &settings); } static void do_pinch_brush_task_cb_ex(void *__restrict userdata, @@ -1967,7 +1970,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1976,7 +1979,7 @@ void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode float area_co[3]; float mat[4][4]; - calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co); + calc_sculpt_plane(sd, ob, nodes, area_no, area_co); /* delay the first daub because grab delta is not setup */ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { @@ -2010,8 +2013,8 @@ void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode data.stroke_xz = stroke_xz; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_pinch_brush_task_cb_ex, &settings); } static void do_grab_brush_task_cb_ex(void *__restrict userdata, @@ -2082,7 +2085,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -2102,8 +2105,8 @@ void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) data.grab_delta = grab_delta; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_grab_brush_task_cb_ex, &settings); } static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, @@ -2196,7 +2199,7 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -2216,8 +2219,8 @@ void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in data.grab_delta = grab_delta; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_elastic_deform_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_elastic_deform_brush_task_cb_ex, &settings); } /** \} */ @@ -2280,7 +2283,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -2307,8 +2310,8 @@ void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to data.offset = offset; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_draw_sharp_brush_task_cb_ex, &settings); } /** \} */ @@ -2532,7 +2535,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -2550,15 +2553,15 @@ void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); if (ss->cache->alt_smooth) { SCULPT_boundary_info_ensure(ob); for (int i = 0; i < 4; i++) { - BLI_task_parallel_range(0, totnode, &data, do_topology_relax_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_topology_relax_task_cb_ex, &settings); } } else { - BLI_task_parallel_range(0, totnode, &data, do_topology_slide_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_topology_slide_task_cb_ex, &settings); } } @@ -2619,7 +2622,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, Span nodes) { Brush *brush = BKE_paint_brush(&sd->paint); BKE_curvemapping_init(brush->curve); @@ -2632,8 +2635,9 @@ void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **node data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_displacement_eraser_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_displacement_eraser_brush_task_cb_ex, &settings); } /** \} */ @@ -2752,7 +2756,7 @@ static void do_displacement_smear_store_prev_disp_task_cb_ex( BKE_pbvh_vertex_iter_end; } -void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, Span nodes) { Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; @@ -2782,10 +2786,11 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); BLI_task_parallel_range( - 0, totnode, &data, do_displacement_smear_store_prev_disp_task_cb_ex, &settings); - BLI_task_parallel_range(0, totnode, &data, do_displacement_smear_brush_task_cb_ex, &settings); + 0, nodes.size(), &data, do_displacement_smear_store_prev_disp_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_displacement_smear_brush_task_cb_ex, &settings); } /** \} */ @@ -2865,8 +2870,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_bmesh_topology_rake( - Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength) +void SCULPT_bmesh_topology_rake(Sculpt *sd, Object *ob, Span nodes, float bstrength) { Brush *brush = BKE_paint_brush(&sd->paint); const float strength = clamp_f(bstrength, 0.0f, 1.0f); @@ -2888,9 +2892,9 @@ void SCULPT_bmesh_topology_rake( data.strength = factor; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); - BLI_task_parallel_range(0, totnode, &data, do_topology_rake_bmesh_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_topology_rake_bmesh_task_cb_ex, &settings); } } @@ -2948,7 +2952,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, Span nodes) { Brush *brush = BKE_paint_brush(&sd->paint); @@ -2960,21 +2964,21 @@ void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int tot data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_mask_brush_draw_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_mask_brush_draw_task_cb_ex, &settings); } -void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); switch ((BrushMaskTool)brush->mask_tool) { case BRUSH_MASK_DRAW: - SCULPT_do_mask_brush_draw(sd, ob, nodes, totnode); + SCULPT_do_mask_brush_draw(sd, ob, nodes); break; case BRUSH_MASK_SMOOTH: - SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true); + SCULPT_smooth(sd, ob, nodes, ss->cache->bstrength, true); break; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.cc b/source/blender/editors/sculpt_paint/sculpt_cloth.cc index a5673526d7b..c2da182d45b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.cc +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.cc @@ -12,6 +12,7 @@ #include "BLI_math.h" #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "DNA_brush_types.h" #include "DNA_customdata_types.h" @@ -53,6 +54,8 @@ #include #include +using blender::Vector; + static void cloth_brush_simulation_location_get(SculptSession *ss, const Brush *brush, float r_location[3]) @@ -69,13 +72,10 @@ static void cloth_brush_simulation_location_get(SculptSession *ss, copy_v3_v3(r_location, ss->cache->location); } -PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, - Brush *brush, - int *r_totnode) +Vector SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, Brush *brush) { BLI_assert(ss->cache); BLI_assert(brush->sculpt_tool == SCULPT_TOOL_CLOTH); - PBVHNode **nodes = nullptr; switch (brush->cloth_simulation_area_type) { case BRUSH_CLOTH_SIMULATION_AREA_LOCAL: { @@ -85,11 +85,10 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, data.original = false; data.ignore_fully_ineffective = false; data.center = ss->cache->initial_location; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); - } break; + return blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data); + } case BRUSH_CLOTH_SIMULATION_AREA_GLOBAL: - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, r_totnode); - break; + return blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); case BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC: { SculptSearchSphereData data{}; data.ss = ss; @@ -97,11 +96,12 @@ PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, data.original = false; data.ignore_fully_ineffective = false; data.center = ss->cache->location; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); - } break; + return blender::bke::pbvh::search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data); + } } - return nodes; + BLI_assert_unreachable(); + return Vector(); } static float cloth_brush_simulation_falloff_get(const Brush *brush, @@ -901,8 +901,10 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss, } } -void SCULPT_cloth_brush_do_simulation_step( - Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode) +void SCULPT_cloth_brush_do_simulation_step(Sculpt *sd, + Object *ob, + SculptClothSimulation *cloth_sim, + Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -920,12 +922,15 @@ void SCULPT_cloth_brush_do_simulation_step( solve_simulation_data.cloth_sim = cloth_sim; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range( - 0, totnode, &solve_simulation_data, do_cloth_brush_solve_simulation_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, + nodes.size(), + &solve_simulation_data, + do_cloth_brush_solve_simulation_task_cb_ex, + &settings); } -static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -970,7 +975,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR || brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) { - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no, area_co); /* Initialize stroke local space matrix. */ cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry); @@ -1003,9 +1008,9 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod } TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); BLI_task_parallel_range( - 0, totnode, &apply_forces_data, do_cloth_brush_apply_forces_task_cb_ex, &settings); + 0, nodes.size(), &apply_forces_data, do_cloth_brush_apply_forces_task_cb_ex, &settings); } /* Allocates nodes state and initializes them to Uninitialized, so constraints can be created for @@ -1013,18 +1018,15 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod static void cloth_sim_initialize_default_node_state(SculptSession *ss, SculptClothSimulation *cloth_sim) { - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); cloth_sim->node_state = static_cast( - MEM_malloc_arrayN(totnode, sizeof(eSculptClothNodeSimState), "node sim state")); + MEM_malloc_arrayN(nodes.size(), sizeof(eSculptClothNodeSimState), "node sim state")); cloth_sim->node_state_index = BLI_ghash_ptr_new("node sim state indices"); - for (int i = 0; i < totnode; i++) { + for (int i = 0; i < nodes.size(); i++) { cloth_sim->node_state[i] = SCULPT_CLOTH_NODE_UNINITIALIZED; BLI_ghash_insert(cloth_sim->node_state_index, nodes[i], POINTER_FROM_INT(i)); } - MEM_SAFE_FREE(nodes); } SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob, @@ -1077,8 +1079,7 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob, void SCULPT_cloth_brush_ensure_nodes_constraints( Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode, + Span nodes, SculptClothSimulation *cloth_sim, /* Cannot be `const`, because it is assigned to a `non-const` variable. * NOLINTNEXTLINE: readability-non-const-parameter. */ @@ -1092,7 +1093,7 @@ void SCULPT_cloth_brush_ensure_nodes_constraints( /* Currently all constrains are added to the same global array which can't be accessed from * different threads. */ TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, false, totnode); + BKE_pbvh_parallel_range_settings(&settings, false, nodes.size()); cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints"); @@ -1105,8 +1106,11 @@ void SCULPT_cloth_brush_ensure_nodes_constraints( build_constraints_data.cloth_sim_initial_location = initial_location; build_constraints_data.cloth_sim_radius = radius; - BLI_task_parallel_range( - 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); + BLI_task_parallel_range(0, + nodes.size(), + &build_constraints_data, + do_cloth_brush_build_constraints_task_cb_ex, + &settings); BLI_edgeset_free(cloth_sim->created_length_constraints); } @@ -1143,21 +1147,18 @@ void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSim } } -void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, - PBVHNode **nodes, - int totnode) +void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, Span nodes) { /* Activate the nodes inside the simulation area. */ - for (int n = 0; n < totnode; n++) { - const int node_index = POINTER_AS_INT(BLI_ghash_lookup(cloth_sim->node_state_index, nodes[n])); + for (PBVHNode *node : nodes) { + const int node_index = POINTER_AS_INT(BLI_ghash_lookup(cloth_sim->node_state_index, node)); cloth_sim->node_state[node_index] = SCULPT_CLOTH_NODE_ACTIVE; } } static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode) + Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1166,10 +1167,10 @@ static void sculpt_cloth_ensure_constraints_in_simulation_area(Sculpt *sd, float sim_location[3]; cloth_brush_simulation_location_get(ss, brush, sim_location); SCULPT_cloth_brush_ensure_nodes_constraints( - sd, ob, nodes, totnode, ss->cache->cloth_sim, sim_location, limit); + sd, ob, nodes, ss->cache->cloth_sim, sim_location, limit); } -void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1201,7 +1202,7 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode * as this will cause the ensure constraints function to skip the node in the next symmetry * passes. It needs to build the constraints here and skip simulating the first step, so all * passes can add their constraints to all affected nodes. */ - sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode); + sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes); } /* The first step of a symmetry pass is never simulated as deformation modes need valid delta * for brush tip alignment. */ @@ -1209,19 +1210,19 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode } /* Ensure the constraints for the nodes. */ - sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode); + sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes); /* Store the initial state in the simulation. */ SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim); /* Enable the nodes that should be simulated. */ - SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode); + SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes); /* Apply forces to the vertices. */ - cloth_brush_apply_brush_foces(sd, ob, nodes, totnode); + cloth_brush_apply_brush_foces(sd, ob, nodes); /* Update and write the simulation to the nodes. */ - SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); + SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes); } void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim) @@ -1530,17 +1531,16 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent data.filter_strength = filter_strength; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); BLI_task_parallel_range( - 0, ss->filter_cache->totnode, &data, cloth_filter_apply_forces_task_cb, &settings); + 0, ss->filter_cache->nodes.size(), &data, cloth_filter_apply_forces_task_cb, &settings); /* Activate all nodes. */ - SCULPT_cloth_sim_activate_nodes( - ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode); + SCULPT_cloth_sim_activate_nodes(ss->filter_cache->cloth_sim, ss->filter_cache->nodes); /* Update and write the simulation to the nodes. */ SCULPT_cloth_brush_do_simulation_step( - sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode); + sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes); if (ss->deform_modifiers_active || ss->shapekey_active) { SCULPT_flush_stroke_deform(sd, ob, true); @@ -1597,13 +1597,8 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_cloth_brush_simulation_init(ss, ss->filter_cache->cloth_sim); float origin[3] = {0.0f, 0.0f, 0.0f}; - SCULPT_cloth_brush_ensure_nodes_constraints(sd, - ob, - ss->filter_cache->nodes, - ss->filter_cache->totnode, - ss->filter_cache->cloth_sim, - origin, - FLT_MAX); + SCULPT_cloth_brush_ensure_nodes_constraints( + sd, ob, ss->filter_cache->nodes, ss->filter_cache->cloth_sim, origin, FLT_MAX); const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); if (use_face_sets) { diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.cc b/source/blender/editors/sculpt_paint/sculpt_detail.cc index 6a7f8caf96f..b1bbc211d1e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.cc +++ b/source/blender/editors/sculpt_paint/sculpt_detail.cc @@ -82,17 +82,15 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op) SculptSession *ss = ob->sculpt; float size; float bb_min[3], bb_max[3], center[3], dim[3]; - int totnodes; - PBVHNode **nodes; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnodes); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); - if (!totnodes) { + if (nodes.is_empty()) { return OPERATOR_CANCELLED; } - for (int i = 0; i < totnodes; i++) { - BKE_pbvh_node_mark_topology_update(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_topology_update(node); } /* Get the bounding box, its center and size. */ BKE_pbvh_bounding_box(ob->sculpt->pbvh, bb_min, bb_max); @@ -111,12 +109,11 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op) while (BKE_pbvh_bmesh_update_topology( ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false)) { - for (int i = 0; i < totnodes; i++) { - BKE_pbvh_node_mark_topology_update(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_topology_update(node); } } - MEM_SAFE_FREE(nodes); SCULPT_undo_push_end(ob); /* Force rebuild of PBVH for better BB placement. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index b22509cf40b..2aeff54e39f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -1138,14 +1138,13 @@ static void sculpt_expand_cache_data_free(ExpandCache *expand_cache) if (expand_cache->snap_enabled_face_sets) { BLI_gset_free(expand_cache->snap_enabled_face_sets, nullptr); } - MEM_SAFE_FREE(expand_cache->nodes); MEM_SAFE_FREE(expand_cache->vert_falloff); MEM_SAFE_FREE(expand_cache->face_falloff); MEM_SAFE_FREE(expand_cache->original_mask); MEM_SAFE_FREE(expand_cache->original_face_sets); MEM_SAFE_FREE(expand_cache->initial_face_sets); MEM_SAFE_FREE(expand_cache->original_colors); - MEM_SAFE_FREE(expand_cache); + MEM_delete(expand_cache); } static void sculpt_expand_cache_free(SculptSession *ss) @@ -1161,14 +1160,11 @@ static void sculpt_expand_cache_free(SculptSession *ss) */ static void sculpt_expand_restore_face_set_data(SculptSession *ss, ExpandCache *expand_cache) { - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - for (int n = 0; n < totnode; n++) { - PBVHNode *node = nodes[n]; + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { BKE_pbvh_node_mark_redraw(node); } - MEM_freeN(nodes); + for (int i = 0; i < ss->totfaces; i++) { ss->face_sets[i] = expand_cache->original_face_sets[i]; } @@ -1176,11 +1172,9 @@ static void sculpt_expand_restore_face_set_data(SculptSession *ss, ExpandCache * static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *expand_cache) { - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - for (int n = 0; n < totnode; n++) { - PBVHNode *node = nodes[n]; + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); + + for (PBVHNode *node : nodes) { PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { SCULPT_vertex_color_set(ss, vd.vertex, expand_cache->original_colors[vd.index]); @@ -1188,16 +1182,12 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp BKE_pbvh_vertex_iter_end; BKE_pbvh_node_mark_redraw(node); } - MEM_freeN(nodes); } static void sculpt_expand_restore_mask_data(SculptSession *ss, ExpandCache *expand_cache) { - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - for (int n = 0; n < totnode; n++) { - PBVHNode *node = nodes[n]; + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { *vd.mask = expand_cache->original_mask[vd.index]; @@ -1205,7 +1195,6 @@ static void sculpt_expand_restore_mask_data(SculptSession *ss, ExpandCache *expa BKE_pbvh_vertex_iter_end; BKE_pbvh_node_mark_redraw(node); } - MEM_freeN(nodes); } /* Main function to restore the original state of the data to how it was before starting the expand @@ -1327,8 +1316,8 @@ static void sculpt_expand_face_sets_update(SculptSession *ss, ExpandCache *expan } } - for (int i = 0; i < expand_cache->totnode; i++) { - BKE_pbvh_node_mark_redraw(ss->expand_cache->nodes[i]); + for (PBVHNode *node : ss->expand_cache->nodes) { + BKE_pbvh_node_mark_redraw(node); } } @@ -1501,19 +1490,19 @@ static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const PBVHV data.nodes = expand_cache->nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, expand_cache->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, expand_cache->nodes.size()); switch (expand_cache->target) { case SCULPT_EXPAND_TARGET_MASK: BLI_task_parallel_range( - 0, expand_cache->totnode, &data, sculpt_expand_mask_update_task_cb, &settings); + 0, expand_cache->nodes.size(), &data, sculpt_expand_mask_update_task_cb, &settings); break; case SCULPT_EXPAND_TARGET_FACE_SETS: sculpt_expand_face_sets_update(ss, expand_cache); break; case SCULPT_EXPAND_TARGET_COLORS: BLI_task_parallel_range( - 0, expand_cache->totnode, &data, sculpt_expand_colors_update_task_cb, &settings); + 0, expand_cache->nodes.size(), &data, sculpt_expand_colors_update_task_cb, &settings); break; } @@ -1606,13 +1595,10 @@ static void sculpt_expand_finish(bContext *C) SCULPT_undo_push_end(ob); /* Tag all nodes to redraw to avoid artifacts after the fast partial updates. */ - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - for (int n = 0; n < totnode; n++) { - BKE_pbvh_node_mark_update_mask(nodes[n]); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update_mask(node); } - MEM_freeN(nodes); switch (ss->expand_cache->target) { case SCULPT_EXPAND_TARGET_MASK: @@ -2105,29 +2091,25 @@ static void sculpt_expand_cache_initial_config_set(bContext *C, static void sculpt_expand_undo_push(Object *ob, ExpandCache *expand_cache) { SculptSession *ss = ob->sculpt; - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); switch (expand_cache->target) { case SCULPT_EXPAND_TARGET_MASK: - for (int i = 0; i < totnode; i++) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); } break; case SCULPT_EXPAND_TARGET_FACE_SETS: - for (int i = 0; i < totnode; i++) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS); } break; case SCULPT_EXPAND_TARGET_COLORS: - for (int i = 0; i < totnode; i++) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COLOR); } break; } - - MEM_freeN(nodes); } static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -2140,7 +2122,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even SCULPT_stroke_id_next(ob); /* Create and configure the Expand Cache. */ - ss->expand_cache = MEM_cnew(__func__); + ss->expand_cache = MEM_new(__func__); sculpt_expand_cache_initial_config_set(C, op, ss->expand_cache); /* Update object. */ @@ -2171,21 +2153,17 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even } if (ok) { - int nodes_num; - PBVHNode **nodes; - /* TODO: implement SCULPT_vertex_mask_set and use it here. */ - - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &nodes_num); - for (int i = 0; i < nodes_num; i++) { + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { *vd.mask = 1.0f; } BKE_pbvh_vertex_iter_end; - BKE_pbvh_node_mark_update_mask(nodes[i]); + BKE_pbvh_node_mark_update_mask(node); } } } @@ -2223,8 +2201,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even sculpt_expand_set_initial_components_for_mouse(C, ob, ss->expand_cache, mouse); /* Cache PBVH nodes. */ - BKE_pbvh_search_gather( - ss->pbvh, nullptr, nullptr, &ss->expand_cache->nodes, &ss->expand_cache->totnode); + ss->expand_cache->nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); /* Store initial state. */ sculpt_expand_original_state_store(ob, ss->expand_cache); diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 42ce5006dce..831bd84232b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -11,6 +11,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_array.hh" #include "BLI_bit_vector.hh" #include "BLI_function_ref.hh" #include "BLI_hash.h" @@ -55,6 +56,7 @@ #include "bmesh.h" +using blender::Array; using blender::float3; using blender::Vector; @@ -252,7 +254,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -273,16 +275,17 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); if (ss->cache->alt_smooth) { SCULPT_boundary_info_ensure(ob); for (int i = 0; i < 4; i++) { data.iteration = i; - BLI_task_parallel_range(0, totnode, &data, do_relax_face_sets_brush_task_cb_ex, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_relax_face_sets_brush_task_cb_ex, &settings); } } else { - BLI_task_parallel_range(0, totnode, &data, do_draw_face_sets_brush_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_draw_face_sets_brush_task_cb_ex, &settings); } } @@ -350,17 +353,15 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) float threshold = 0.5f; PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); - if (!nodes) { + if (nodes.is_empty()) { return OPERATOR_CANCELLED; } SCULPT_undo_push_begin(ob, op); - for (const int i : blender::IndexRange(totnode)) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS); } const int next_face_set = SCULPT_face_set_next_available_get(ss); @@ -427,12 +428,10 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) }); } - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_redraw(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_redraw(node); } - MEM_SAFE_FREE(nodes); - SCULPT_undo_push_end(ob); SCULPT_tag_update_overlays(C); @@ -638,17 +637,15 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) } PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); - if (!nodes) { + if (nodes.is_empty()) { return OPERATOR_CANCELLED; } SCULPT_undo_push_begin(ob, op); - for (const int i : blender::IndexRange(totnode)) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS); } const float threshold = RNA_float_get(op->ptr, "threshold"); @@ -734,14 +731,12 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */ SCULPT_visibility_sync_all_from_faces(ob); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_update_visibility(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update_visibility(node); } BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); - MEM_SAFE_FREE(nodes); - if (BKE_pbvh_type(pbvh) == PBVH_FACES) { BKE_mesh_flush_hidden_from_verts(mesh); } @@ -836,21 +831,17 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) const int tot_vert = SCULPT_vertex_count_get(ss); PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode **nodes; - int totnode; + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); - - if (totnode == 0) { - MEM_SAFE_FREE(nodes); + if (nodes.is_empty()) { return OPERATOR_CANCELLED; } const int active_face_set = SCULPT_active_face_set_get(ss); SCULPT_undo_push_begin(ob, op); - for (int i = 0; i < totnode; i++) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_HIDDEN); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); } switch (mode) { @@ -940,14 +931,12 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) SCULPT_visibility_sync_all_from_faces(ob); SCULPT_undo_push_end(ob); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_update_visibility(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update_visibility(node); } BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); - MEM_SAFE_FREE(nodes); - SCULPT_tag_update_overlays(C); return OPERATOR_FINISHED; @@ -1008,8 +997,6 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator * /*op } PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode **nodes; - int totnode; Mesh *mesh = static_cast(ob->data); mesh->face_sets_color_seed += 1; @@ -1021,13 +1008,11 @@ static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator * /*op } BKE_pbvh_face_sets_color_set(pbvh, mesh->face_sets_color_seed, mesh->face_sets_color_default); - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_redraw(nodes[i]); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_redraw(node); } - MEM_SAFE_FREE(nodes); - SCULPT_tag_update_overlays(C); return OPERATOR_FINISHED; @@ -1355,7 +1340,7 @@ static void sculpt_face_set_edit_modify_geometry(bContext *C, WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh); } -static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode) +static void face_set_edit_do_post_visibility_updates(Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; PBVH *pbvh = ss->pbvh; @@ -1364,8 +1349,8 @@ static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **node /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */ SCULPT_visibility_sync_all_from_faces(ob); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_update_visibility(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update_visibility(node); } BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); @@ -1382,21 +1367,18 @@ static void sculpt_face_set_edit_modify_face_sets(Object *ob, wmOperator *op) { PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); - if (!nodes) { + if (nodes.is_empty()) { return; } SCULPT_undo_push_begin(ob, op); - for (const int i : blender::IndexRange(totnode)) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_FACE_SETS); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS); } sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden); SCULPT_undo_push_end(ob); - face_set_edit_do_post_visibility_updates(ob, nodes, totnode); - MEM_freeN(nodes); + face_set_edit_do_post_visibility_updates(ob, nodes); } static void sculpt_face_set_edit_modify_coordinates(bContext *C, @@ -1408,17 +1390,15 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C, Sculpt *sd = CTX_data_tool_settings(C)->sculpt; SculptSession *ss = ob->sculpt; PBVH *pbvh = ss->pbvh; - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); const float strength = RNA_float_get(op->ptr, "strength"); SCULPT_undo_push_begin(ob, op); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_update(nodes[i]); - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COORDS); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update(node); + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COORDS); } sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, false, strength); @@ -1428,7 +1408,6 @@ static void sculpt_face_set_edit_modify_coordinates(bContext *C, SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS); SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS); SCULPT_undo_push_end(ob); - MEM_freeN(nodes); } static bool sculpt_face_set_edit_init(bContext *C, wmOperator *op) diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.cc b/source/blender/editors/sculpt_paint/sculpt_filter_color.cc index bc18305722c..bdf42b895cf 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.cc @@ -289,8 +289,9 @@ static void sculpt_color_filter_apply(bContext *C, wmOperator *op, Object *ob) TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); - BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, color_filter_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); + BLI_task_parallel_range( + 0, ss->filter_cache->nodes.size(), &data, color_filter_task_cb, &settings); SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR); } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc index f9b1db62bf1..e1949d8c063 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.cc @@ -161,9 +161,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); const Scene *scene = CTX_data_scene(C); - PBVHNode **nodes; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - int totnode; int filter_type = RNA_enum_get(op->ptr, "filter_type"); MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); @@ -182,11 +180,11 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) int num_verts = SCULPT_vertex_count_get(ss); - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); SCULPT_undo_push_begin(ob, op); - for (int i = 0; i < totnode; i++) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); + for (PBVHNode *node : nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); } float *prev_mask = nullptr; @@ -217,16 +215,14 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) data.prev_mask = prev_mask; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, mask_filter_task_cb, &settings); if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) { MEM_freeN(prev_mask); } } - MEM_SAFE_FREE(nodes); - SCULPT_undo_push_end(ob); SCULPT_tag_update_overlays(C); @@ -234,8 +230,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void SCULPT_mask_filter_smooth_apply( - Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations) +void SCULPT_mask_filter_smooth_apply(Sculpt *sd, + Object *ob, + Span nodes, + const int smooth_iterations) { SculptThreadedTaskData data{}; data.sd = sd; @@ -245,8 +243,8 @@ void SCULPT_mask_filter_smooth_apply( for (int i = 0; i < smooth_iterations; i++) { TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, mask_filter_task_cb, &settings); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc index bc7f84028a4..853e8983ca7 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.cc @@ -117,7 +117,7 @@ void SCULPT_filter_cache_init(bContext *C, SculptSession *ss = ob->sculpt; PBVH *pbvh = ob->sculpt->pbvh; - ss->filter_cache = MEM_cnew(__func__); + ss->filter_cache = MEM_new(__func__); ss->filter_cache->start_filter_strength = start_strength; ss->filter_cache->random_seed = rand(); @@ -132,14 +132,11 @@ void SCULPT_filter_cache_init(bContext *C, search_data.radius_squared = FLT_MAX; search_data.ignore_fully_ineffective = true; - BKE_pbvh_search_gather(pbvh, - SCULPT_search_sphere_cb, - &search_data, - &ss->filter_cache->nodes, - &ss->filter_cache->totnode); + ss->filter_cache->nodes = blender::bke::pbvh::search_gather( + pbvh, SCULPT_search_sphere_cb, &search_data); - for (int i = 0; i < ss->filter_cache->totnode; i++) { - BKE_pbvh_node_mark_normals_update(ss->filter_cache->nodes[i]); + for (PBVHNode *node : ss->filter_cache->nodes) { + BKE_pbvh_node_mark_normals_update(node); } /* `mesh->runtime.subdiv_ccg` is not available. Updating of the normals is done during drawing. @@ -155,9 +152,9 @@ void SCULPT_filter_cache_init(bContext *C, data.filter_undo_type = undo_type; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); BLI_task_parallel_range( - 0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings); + 0, ss->filter_cache->nodes.size(), &data, filter_cache_init_task_cb, &settings); /* Setup orientation matrices. */ copy_m4_m4(ss->filter_cache->obmat, ob->object_to_world); @@ -180,8 +177,7 @@ void SCULPT_filter_cache_init(bContext *C, float mval_fl[2] = {float(mval[0]), float(mval[1])}; if (vc.rv3d && SCULPT_stroke_get_location(C, co, mval_fl, false)) { - PBVHNode **nodes; - int totnode; + Vector nodes; /* Get radius from brush. */ Brush *brush = BKE_paint_brush(&sd->paint); @@ -206,19 +202,16 @@ void SCULPT_filter_cache_init(bContext *C, search_data2.radius_squared = radius * radius; search_data2.ignore_fully_ineffective = true; - BKE_pbvh_search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2, &nodes, &totnode); + nodes = blender::bke::pbvh::search_gather(pbvh, SCULPT_search_sphere_cb, &search_data2); if (BKE_paint_brush(&sd->paint) && - SCULPT_pbvh_calc_area_normal( - brush, ob, nodes, totnode, true, ss->filter_cache->initial_normal)) { + SCULPT_pbvh_calc_area_normal(brush, ob, nodes, true, ss->filter_cache->initial_normal)) { copy_v3_v3(ss->last_normal, ss->filter_cache->initial_normal); } else { copy_v3_v3(ss->filter_cache->initial_normal, ss->last_normal); } - MEM_SAFE_FREE(nodes); - /* Update last stroke location */ mul_m4_v3(ob->object_to_world, co); @@ -257,7 +250,6 @@ void SCULPT_filter_cache_free(SculptSession *ss) if (ss->filter_cache->automasking) { SCULPT_automasking_cache_free(ss->filter_cache->automasking); } - MEM_SAFE_FREE(ss->filter_cache->nodes); MEM_SAFE_FREE(ss->filter_cache->mask_update_it); MEM_SAFE_FREE(ss->filter_cache->prev_mask); MEM_SAFE_FREE(ss->filter_cache->normal_factor); @@ -267,7 +259,7 @@ void SCULPT_filter_cache_free(SculptSession *ss) MEM_SAFE_FREE(ss->filter_cache->detail_directions); MEM_SAFE_FREE(ss->filter_cache->limit_surface_co); MEM_SAFE_FREE(ss->filter_cache->pre_smoothed_color); - MEM_SAFE_FREE(ss->filter_cache); + MEM_delete(ss->filter_cache); } typedef enum eSculptMeshFilterType { @@ -778,12 +770,13 @@ static void sculpt_mesh_filter_apply(bContext *C, wmOperator *op) data.filter_strength = filter_strength; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); - BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, mesh_filter_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); + BLI_task_parallel_range( + 0, ss->filter_cache->nodes.size(), &data, mesh_filter_task_cb, &settings); if (filter_type == MESH_FILTER_SURFACE_SMOOTH) { BLI_task_parallel_range(0, - ss->filter_cache->totnode, + ss->filter_cache->nodes.size(), &data, mesh_filter_surface_smooth_displace_task_cb, &settings); @@ -872,22 +865,19 @@ static void sculpt_mesh_filter_cancel(bContext *C, wmOperator * /*op*/) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; - PBVHNode **nodes; - int nodes_num; if (!ss || !ss->pbvh) { return; } /* Gather all PBVH leaf nodes. */ - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &nodes_num); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); - for (int i : IndexRange(nodes_num)) { - PBVHNode *node = nodes[i]; + for (PBVHNode *node : nodes) { PBVHVertexIter vd; SculptOrigVertData orig_data; - SCULPT_orig_vert_data_init(&orig_data, ob, nodes[i], SCULPT_UNDO_COORDS); + SCULPT_orig_vert_data_init(&orig_data, ob, node, SCULPT_UNDO_COORDS); BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); @@ -899,7 +889,6 @@ static void sculpt_mesh_filter_cancel(bContext *C, wmOperator * /*op*/) BKE_pbvh_node_mark_update(node); } - MEM_SAFE_FREE(nodes); BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB); } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index b86ae773630..abd0504bdc4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -22,7 +22,9 @@ #include "BLI_compiler_attrs.h" #include "BLI_compiler_compat.h" #include "BLI_gsqueue.h" +#include "BLI_span.hh" #include "BLI_threads.h" +#include "BLI_vector.hh" #include "ED_view3d.h" @@ -46,6 +48,9 @@ struct wmKeyConfig; struct wmOperator; struct wmOperatorType; +using blender::Span; +using blender::Vector; + /* Updates */ /* -------------------------------------------------------------------- */ @@ -243,8 +248,7 @@ struct SculptThreadedTaskData { Sculpt *sd; Object *ob; const Brush *brush; - PBVHNode **nodes; - int totnode; + Span nodes; VPaint *vp; WPaintData *wpd; @@ -469,8 +473,7 @@ struct FilterCache { float (*limit_surface_co)[3]; /* unmasked nodes */ - PBVHNode **nodes; - int totnode; + Vector nodes; /* Cloth filter. */ SculptClothSimulation *cloth_sim; @@ -781,8 +784,7 @@ struct ExpandCache { /* Cached PBVH nodes. This allows to skip gathering all nodes from the PBVH each time expand * needs to update the state of the elements. */ - PBVHNode **nodes; - int totnode; + Vector nodes; /* Expand state options. */ @@ -1171,18 +1173,16 @@ BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush) } void SCULPT_calc_brush_plane( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]); + Sculpt *sd, Object *ob, Span nodes, float r_area_no[3], float r_area_co[3]); -void SCULPT_calc_area_normal( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3]); +void SCULPT_calc_area_normal(Sculpt *sd, Object *ob, Span nodes, float r_area_no[3]); /** * This calculates flatten center and area normal together, * amortizing the memory bandwidth and loop overhead to calculate both at the same time. */ void SCULPT_calc_area_normal_and_center( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3]); -void SCULPT_calc_area_center( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3]); + Sculpt *sd, Object *ob, Span nodes, float r_area_no[3], float r_area_co[3]); +void SCULPT_calc_area_center(Sculpt *sd, Object *ob, Span nodes, float r_area_co[3]); PBVHVertRef SCULPT_nearest_vertex_get( Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original); @@ -1453,8 +1453,10 @@ void SCULPT_filter_cache_init(bContext *C, void SCULPT_filter_cache_free(SculptSession *ss); void SCULPT_mesh_filter_properties(wmOperatorType *ot); -void SCULPT_mask_filter_smooth_apply( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, int smooth_iterations); +void SCULPT_mask_filter_smooth_apply(Sculpt *sd, + Object *ob, + Span nodes, + int smooth_iterations); /* Filter orientation utils. */ void SCULPT_filter_to_orientation_space(float r_v[3], FilterCache *filter_cache); @@ -1468,7 +1470,7 @@ void SCULPT_filter_zero_disabled_axis_components(float r_v[3], FilterCache *filt * \{ */ /* Main cloth brush function */ -void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, Span nodes); void SCULPT_cloth_simulation_free(SculptClothSimulation *cloth_sim); @@ -1482,20 +1484,19 @@ SculptClothSimulation *SCULPT_cloth_brush_simulation_create(Object *ob, bool needs_deform_coords); void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim); -void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, - PBVHNode **nodes, - int totnode); +void SCULPT_cloth_sim_activate_nodes(SculptClothSimulation *cloth_sim, Span nodes); void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSimulation *cloth_sim); -void SCULPT_cloth_brush_do_simulation_step( - Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode); +void SCULPT_cloth_brush_do_simulation_step(Sculpt *sd, + Object *ob, + SculptClothSimulation *cloth_sim, + Span nodes); void SCULPT_cloth_brush_ensure_nodes_constraints(Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode, + Span nodes, SculptClothSimulation *cloth_sim, float initial_location[3], float radius); @@ -1516,9 +1517,7 @@ void SCULPT_cloth_plane_falloff_preview_draw(uint gpuattr, const float outline_col[3], float outline_alpha); -PBVHNode **SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, - Brush *brush, - int *r_totnode); +Vector SCULPT_cloth_brush_affected_nodes_gather(SculptSession *ss, Brush *brush); BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) { @@ -1554,8 +1553,8 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss, PBVHVertRef vertex); void SCULPT_smooth( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength, bool smooth_mask); -void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); + Sculpt *sd, Object *ob, Span nodes, float bstrength, bool smooth_mask); +void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, Span nodes); /* Surface Smooth Brush. */ @@ -1572,7 +1571,7 @@ void SCULPT_surface_smooth_displace_step(SculptSession *ss, PBVHVertRef vertex, float beta, float fade); -void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, Span nodes); /* Slide/Relax */ void SCULPT_relax_vertex(SculptSession *ss, @@ -1588,8 +1587,7 @@ void SCULPT_relax_vertex(SculptSession *ss, */ bool SCULPT_pbvh_calc_area_normal(const Brush *brush, Object *ob, - PBVHNode **nodes, - int totnode, + Span nodes, bool use_threading, float r_area_no[3]); @@ -1745,7 +1743,7 @@ void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot); /** * Main Brush Function. */ -void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, Span nodes); /** * Calculate the pose origin and (Optionally the pose factor) * that is used when using the pose brush. @@ -1782,7 +1780,7 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object, float radius); void SCULPT_boundary_data_free(SculptBoundary *boundary); /* Main Brush Function. */ -void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, Span nodes); void SCULPT_boundary_edges_preview_draw(uint gpuattr, SculptSession *ss, @@ -1792,30 +1790,28 @@ void SCULPT_boundary_pivot_line_preview_draw(uint gpuattr, SculptSession *ss); /* Multi-plane Scrape Brush. */ /* Main Brush Function. */ -void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, Span nodes); void SCULPT_multiplane_scrape_preview_draw(uint gpuattr, Brush *brush, SculptSession *ss, const float outline_col[3], float outline_alpha); /* Draw Face Sets Brush. */ -void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, Span nodes); /* Paint Brush. */ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode, - PBVHNode **texnodes, - int texnodes_num) ATTR_NONNULL(); + Span nodes, + Span texnodes); /** * \brief Get the image canvas for painting on the given object. * - * \return #true if an image is found. The #r_image and #r_image_user fields are filled with the - * image and image user. Returns false when the image isn't found. In the later case the r_image - * and r_image_user are set to NULL. + * \return #true if an image is found. The #r_image and #r_image_user fields are filled with + * the image and image user. Returns false when the image isn't found. In the later case the + * r_image and r_image_user are set to NULL. */ bool SCULPT_paint_image_canvas_get(PaintModeSettings *paint_mode_settings, Object *ob, @@ -1824,44 +1820,42 @@ bool SCULPT_paint_image_canvas_get(PaintModeSettings *paint_mode_settings, void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, - PBVHNode **texnodes, - int texnode_num) ATTR_NONNULL(); + Span texnodes); bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob) ATTR_NONNULL(); /* Smear Brush. */ -void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, Span nodes); float SCULPT_clay_thumb_get_stabilized_pressure(StrokeCache *cache); -void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_draw_brush(Sculpt *sd, Object *ob, Span nodes); -void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_fill_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_scrape_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_clay_thumb_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_flatten_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_clay_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_clay_strips_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_snake_hook_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_thumb_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_rotate_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_layer_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_inflate_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_nudge_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_crease_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_pinch_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_grab_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_elastic_deform_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_draw_sharp_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_slide_relax_brush(Sculpt *sd, Object *ob, Span nodes); -void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); -void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); +void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_displacement_eraser_brush(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_mask_brush_draw(Sculpt *sd, Object *ob, Span nodes); +void SCULPT_do_mask_brush(Sculpt *sd, Object *ob, Span nodes); /** \} */ -void SCULPT_bmesh_topology_rake( - Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength); +void SCULPT_bmesh_topology_rake(Sculpt *sd, Object *ob, Span nodes, float bstrength); /* end sculpt_brush_types.cc */ diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.cc b/source/blender/editors/sculpt_paint/sculpt_mask_expand.cc index f37b7a51121..303c9b5937b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.cc @@ -46,7 +46,7 @@ static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op) MEM_freeN(op->customdata); - for (int n = 0; n < ss->filter_cache->totnode; n++) { + for (int n = 0; n < ss->filter_cache->nodes.size(); n++) { PBVHNode *node = ss->filter_cache->nodes[n]; if (create_face_set) { for (int i = 0; i < ss->totfaces; i++) { @@ -190,8 +190,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * /* Smooth iterations. */ BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); const int smooth_iterations = RNA_int_get(op->ptr, "smooth_iterations"); - SCULPT_mask_filter_smooth_apply( - sd, ob, ss->filter_cache->nodes, ss->filter_cache->totnode, smooth_iterations); + SCULPT_mask_filter_smooth_apply(sd, ob, ss->filter_cache->nodes, smooth_iterations); /* Pivot position. */ if (RNA_boolean_get(op->ptr, "update_pivot")) { @@ -201,9 +200,9 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * int total = 0; zero_v3(avg); - for (int n = 0; n < ss->filter_cache->totnode; n++) { + for (PBVHNode *node : ss->filter_cache->nodes) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, ss->filter_cache->nodes[n], vd, PBVH_ITER_UNIQUE) { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { const float mask = (vd.mask) ? *vd.mask : 0.0f; if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) { if (SCULPT_check_vertex_pivot_symmetry( @@ -225,8 +224,8 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * MEM_freeN(op->customdata); - for (int i = 0; i < ss->filter_cache->totnode; i++) { - BKE_pbvh_node_mark_redraw(ss->filter_cache->nodes[i]); + for (PBVHNode *node : ss->filter_cache->nodes) { + BKE_pbvh_node_mark_redraw(node); } SCULPT_filter_cache_free(ss); @@ -270,8 +269,9 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); - BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); + BLI_task_parallel_range( + 0, ss->filter_cache->nodes.size(), &data, sculpt_expand_task_cb, &settings); ss->filter_cache->mask_update_current_it = mask_expand_update_it; } @@ -353,23 +353,22 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent int vertex_count = SCULPT_vertex_count_get(ss); - ss->filter_cache = MEM_cnew(__func__); + ss->filter_cache = MEM_new(__func__); - BKE_pbvh_search_gather( - pbvh, nullptr, nullptr, &ss->filter_cache->nodes, &ss->filter_cache->totnode); + ss->filter_cache->nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); SCULPT_undo_push_begin(ob, op); if (create_face_set) { - for (int i = 0; i < ss->filter_cache->totnode; i++) { - BKE_pbvh_node_mark_redraw(ss->filter_cache->nodes[i]); - SCULPT_undo_push_node(ob, ss->filter_cache->nodes[i], SCULPT_UNDO_FACE_SETS); + for (PBVHNode *node : ss->filter_cache->nodes) { + BKE_pbvh_node_mark_redraw(node); + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_FACE_SETS); } } else { - for (int i = 0; i < ss->filter_cache->totnode; i++) { - SCULPT_undo_push_node(ob, ss->filter_cache->nodes[i], SCULPT_UNDO_MASK); - BKE_pbvh_node_mark_redraw(ss->filter_cache->nodes[i]); + for (PBVHNode *node : ss->filter_cache->nodes) { + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); + BKE_pbvh_node_mark_redraw(node); } } @@ -447,8 +446,9 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent data.mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); - BLI_task_parallel_range(0, ss->filter_cache->totnode, &data, sculpt_expand_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); + BLI_task_parallel_range( + 0, ss->filter_cache->nodes.size(), &data, sculpt_expand_task_cb, &settings); const char *status_str = TIP_( "Move the mouse to expand the mask from the active vertex. LMB: confirm mask, ESC/RMB: " diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.cc b/source/blender/editors/sculpt_paint/sculpt_mask_init.cc index 5bcd62e0553..08061226d0a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_init.cc +++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.cc @@ -117,11 +117,9 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op) BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); - if (totnode == 0) { + if (nodes.is_empty()) { return OPERATOR_CANCELLED; } @@ -138,15 +136,14 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op) data.mask_init_seed = PIL_check_seconds_timer(); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, mask_init_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, mask_init_task_cb, &settings); multires_stitch_grids(ob); SCULPT_undo_push_end(ob); BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask); - MEM_SAFE_FREE(nodes); SCULPT_tag_update_overlays(C); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc index 57402fc8673..7cfce6daa29 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.cc @@ -211,7 +211,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, /* Public functions. */ -void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -231,10 +231,10 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, float temp[3]; float mat[4][4]; - SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co); + SCULPT_calc_brush_plane(sd, ob, nodes, area_no_sp, area_co); if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) { - SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no); + SCULPT_calc_area_normal(sd, ob, nodes, area_no); } else { copy_v3_v3(area_no, area_no_sp); @@ -281,19 +281,18 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, sample_data.ob = ob; sample_data.brush = brush; sample_data.nodes = nodes; - sample_data.totnode = totnode; sample_data.mat = mat; MultiplaneScrapeSampleData mssd = {{{0}}}; TaskParallelSettings sample_settings; - BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode); + BKE_pbvh_parallel_range_settings(&sample_settings, true, nodes.size()); sample_settings.func_reduce = calc_multiplane_scrape_surface_reduce; sample_settings.userdata_chunk = &mssd; sample_settings.userdata_chunk_size = sizeof(MultiplaneScrapeSampleData); BLI_task_parallel_range( - 0, totnode, &sample_data, calc_multiplane_scrape_surface_task_cb, &sample_settings); + 0, nodes.size(), &sample_data, calc_multiplane_scrape_surface_task_cb, &sample_settings); float sampled_plane_normals[2][3]; float sampled_plane_co[2][3]; @@ -377,8 +376,9 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, plane_from_point_normal_v3(data.multiplane_scrape_planes[0], area_co, plane_no); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_multiplane_scrape_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_multiplane_scrape_brush_task_cb_ex, &settings); } void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr, diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index ef1a244b89d..7994db70c75 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -817,9 +817,7 @@ static void sculpt_mask_by_color_contiguous(Object *object, SCULPT_floodfill_execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill_cb, &ffd); SCULPT_floodfill_free(&flood); - int totnode; - PBVHNode **nodes; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); SculptThreadedTaskData data{}; data.ob = object; @@ -831,11 +829,9 @@ static void sculpt_mask_by_color_contiguous(Object *object, data.mask_by_color_preserve_mask = preserve_mask; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); BLI_task_parallel_range( - 0, totnode, &data, do_mask_by_color_contiguous_update_nodes_cb, &settings); - - MEM_SAFE_FREE(nodes); + 0, nodes.size(), &data, do_mask_by_color_contiguous_update_nodes_cb, &settings); MEM_freeN(new_mask); } @@ -885,9 +881,7 @@ static void sculpt_mask_by_color_full_mesh(Object *object, { SculptSession *ss = object->sculpt; - int totnode; - PBVHNode **nodes; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); SculptThreadedTaskData data{}; data.ob = object; @@ -898,10 +892,8 @@ static void sculpt_mask_by_color_full_mesh(Object *object, data.mask_by_color_preserve_mask = preserve_mask; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_mask_by_color_task_cb, &settings); - - MEM_SAFE_FREE(nodes); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_mask_by_color_task_cb, &settings); } static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -1011,7 +1003,7 @@ enum CavityBakeSettingsSource { struct AutomaskBakeTaskData { SculptSession *ss; AutomaskingCache *automasking; - PBVHNode **nodes; + Span nodes; CavityBakeMixMode mode; float factor; Object *ob; @@ -1089,10 +1081,7 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) CavityBakeMixMode mode = CavityBakeMixMode(RNA_enum_get(op->ptr, "mix_mode")); float factor = RNA_float_get(op->ptr, "mix_factor"); - PBVHNode **nodes; - int totnode; - - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); AutomaskBakeTaskData tdata; @@ -1165,10 +1154,9 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op) tdata.automasking = SCULPT_automasking_cache_init(&sd2, &brush2, ob); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &tdata, sculpt_bake_cavity_exec_task_cb, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &tdata, sculpt_bake_cavity_exec_task_cb, &settings); - MEM_SAFE_FREE(nodes); SCULPT_automasking_cache_free(tdata.automasking); BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask); @@ -1304,13 +1292,11 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - PBVHNode **nodes; - int totnode; bool with_bmesh = BKE_pbvh_type(ss->pbvh) == PBVH_BMESH; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); - if (!totnode) { + if (nodes.is_empty()) { return OPERATOR_CANCELLED; } @@ -1319,11 +1305,11 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) SCULPT_undo_push_begin(ob, op); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_update_visibility(nodes[i]); + for (PBVHNode *node : nodes) { + BKE_pbvh_node_mark_update_visibility(node); if (!with_bmesh) { - SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_HIDDEN); + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); } } @@ -1367,7 +1353,6 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) BKE_pbvh_update_visibility(ss->pbvh); SCULPT_undo_push_end(ob); - MEM_SAFE_FREE(nodes); SCULPT_tag_update_overlays(C); DEG_id_tag_update(&ob->id, ID_RECALC_SHADING); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.cc b/source/blender/editors/sculpt_paint/sculpt_paint_color.cc index 037d40fc9e8..8f98e422250 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.cc @@ -11,6 +11,7 @@ #include "BLI_math.h" #include "BLI_math_color_blend.h" #include "BLI_task.h" +#include "BLI_vector.hh" #include "DNA_meshdata_types.h" @@ -32,6 +33,8 @@ #include #include +using blender::Vector; + static void do_color_smooth_task_cb_exec(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) @@ -252,13 +255,11 @@ static void sample_wet_paint_reduce(const void *__restrict /*userdata*/, void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode, - PBVHNode **texnodes, - int texnodes_num) + Span nodes, + Span texnodes) { if (SCULPT_use_image_paint_brush(paint_mode_settings, ob)) { - SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, texnodes, texnodes_num); + SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, texnodes); return; } @@ -300,8 +301,8 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, data.mat = mat; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_color_smooth_task_cb_exec, &settings); return; } @@ -321,11 +322,12 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, zero_v4(swptd.color); TaskParallelSettings settings_sample; - BKE_pbvh_parallel_range_settings(&settings_sample, true, totnode); + BKE_pbvh_parallel_range_settings(&settings_sample, true, nodes.size()); settings_sample.func_reduce = sample_wet_paint_reduce; settings_sample.userdata_chunk = &swptd; settings_sample.userdata_chunk_size = sizeof(SampleWetPaintTLSData); - BLI_task_parallel_range(0, totnode, &task_data, do_sample_wet_paint_task_cb, &settings_sample); + BLI_task_parallel_range( + 0, nodes.size(), &task_data, do_sample_wet_paint_task_cb, &settings_sample); if (swptd.tot_samples > 0 && is_finite_v4(swptd.color)) { copy_v4_v4(wet_color, swptd.color); @@ -354,8 +356,8 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, data.mat = mat; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_paint_brush_task_cb_ex, &settings); } static void do_smear_brush_task_cb_exec(void *__restrict userdata, @@ -525,7 +527,7 @@ static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, Span nodes) { Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; @@ -554,15 +556,16 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); /* Smooth colors mode. */ if (ss->cache->alt_smooth) { - BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_color_smooth_task_cb_exec, &settings); } else { /* Smear mode. */ - BLI_task_parallel_range(0, totnode, &data, do_smear_store_prev_colors_task_cb_exec, &settings); - BLI_task_parallel_range(0, totnode, &data, do_smear_brush_task_cb_exec, &settings); + BLI_task_parallel_range( + 0, nodes.size(), &data, do_smear_store_prev_colors_task_cb_exec, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, do_smear_brush_task_cb_exec, &settings); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 3796baa82b8..782b17ccca9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -51,7 +51,7 @@ struct ImageData { struct TexturePaintingUserData { Object *ob; Brush *brush; - PBVHNode **nodes; + Span nodes; ImageData image_data; }; @@ -534,12 +534,9 @@ static void fix_non_manifold_seam_bleeding(PBVH &pbvh, } } -static void fix_non_manifold_seam_bleeding(Object &ob, - const int totnode, - TexturePaintingUserData &user_data) +static void fix_non_manifold_seam_bleeding(Object &ob, TexturePaintingUserData &user_data) { - Vector dirty_tiles = collect_dirty_tiles( - Span(user_data.nodes, totnode)); + Vector dirty_tiles = collect_dirty_tiles(user_data.nodes); fix_non_manifold_seam_bleeding(*ob.sculpt->pbvh, user_data, dirty_tiles); } @@ -583,8 +580,7 @@ bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob) void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, - PBVHNode **texnodes, - int texnodes_num) + Span texnodes) { Brush *brush = BKE_paint_brush(&sd->paint); @@ -598,13 +594,13 @@ void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, } TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, texnodes_num); - BLI_task_parallel_range(0, texnodes_num, &data, do_push_undo_tile, &settings); - BLI_task_parallel_range(0, texnodes_num, &data, do_paint_pixels, &settings); - fix_non_manifold_seam_bleeding(*ob, texnodes_num, data); + BKE_pbvh_parallel_range_settings(&settings, true, texnodes.size()); + BLI_task_parallel_range(0, texnodes.size(), &data, do_push_undo_tile, &settings); + BLI_task_parallel_range(0, texnodes.size(), &data, do_paint_pixels, &settings); + fix_non_manifold_seam_bleeding(*ob, data); TaskParallelSettings settings_flush; - BKE_pbvh_parallel_range_settings(&settings_flush, false, texnodes_num); - BLI_task_parallel_range(0, texnodes_num, &data, do_mark_dirty_regions, &settings_flush); + BKE_pbvh_parallel_range_settings(&settings_flush, false, texnodes.size()); + BLI_task_parallel_range(0, texnodes.size(), &data, do_mark_dirty_regions, &settings_flush); } diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.cc b/source/blender/editors/sculpt_paint/sculpt_pose.cc index 74e3ba9186c..e3ccddd7e40 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.cc +++ b/source/blender/editors/sculpt_paint/sculpt_pose.cc @@ -259,16 +259,14 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, float *r_pose_origin, float *pose_factor) { - PBVHNode **nodes; PBVH *pbvh = ob->sculpt->pbvh; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); + SculptThreadedTaskData data{}; data.sd = sd; data.ob = ob; data.nodes = nodes; - data.totnode = totnode; data.pose_factor = pose_factor; data.pose_initial_co = pose_target; @@ -276,7 +274,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, PoseGrowFactorTLSData gftd; gftd.pos_count = 0; zero_v3(gftd.pos_avg); - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); settings.func_reduce = pose_brush_grow_factor_reduce; settings.userdata_chunk = &gftd; settings.userdata_chunk_size = sizeof(PoseGrowFactorTLSData); @@ -289,7 +287,7 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, zero_v3(gftd.pos_avg); gftd.pos_count = 0; memcpy(data.prev_mask, pose_factor, SCULPT_vertex_count_get(ss) * sizeof(float)); - BLI_task_parallel_range(0, totnode, &data, pose_brush_grow_factor_task_cb_ex, &settings); + BLI_task_parallel_range(0, nodes.size(), &data, pose_brush_grow_factor_task_cb_ex, &settings); if (gftd.pos_count != 0) { mul_v3_fl(gftd.pos_avg, 1.0f / float(gftd.pos_count)); @@ -332,8 +330,6 @@ static void sculpt_pose_grow_pose_factor(Sculpt *sd, } } MEM_freeN(data.prev_mask); - - MEM_SAFE_FREE(nodes); } static bool sculpt_pose_brush_is_vertex_inside_brush_radius(const float vertex[3], @@ -972,11 +968,9 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd, void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br) { - PBVHNode **nodes; PBVH *pbvh = ob->sculpt->pbvh; - int totnode; - BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(pbvh, nullptr, nullptr); SculptThreadedTaskData data{}; data.sd = sd; @@ -993,12 +987,10 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br data.pose_factor = ss->cache->pose_ik_chain->segments[ik].weights; for (int i = 0; i < br->pose_smooth_iterations; i++) { TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, pose_brush_init_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, pose_brush_init_task_cb_ex, &settings); } } - - MEM_SAFE_FREE(nodes); } static void sculpt_pose_do_translate_deform(SculptSession *ss, Brush *brush) @@ -1124,7 +1116,7 @@ static void sculpt_pose_align_pivot_local_space(float r_mat[4][4], ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]); } -void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -1216,8 +1208,8 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_pose_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_pose_brush_task_cb_ex, &settings); } void SCULPT_pose_ik_chain_free(SculptPoseIKChain *ik_chain) diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.cc b/source/blender/editors/sculpt_paint/sculpt_smooth.cc index 696ce178716..8a84fda1d27 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.cc @@ -228,10 +228,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -static void SCULPT_enhance_details_brush(Sculpt *sd, - Object *ob, - PBVHNode **nodes, - const int totnode) +static void SCULPT_enhance_details_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -260,8 +257,8 @@ static void SCULPT_enhance_details_brush(Sculpt *sd, data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_enhance_details_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_enhance_details_brush_task_cb_ex, &settings); } static void do_smooth_brush_task_cb_ex(void *__restrict userdata, @@ -326,12 +323,8 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_end; } -void SCULPT_smooth(Sculpt *sd, - Object *ob, - PBVHNode **nodes, - const int totnode, - float bstrength, - const bool smooth_mask) +void SCULPT_smooth( + Sculpt *sd, Object *ob, Span nodes, float bstrength, const bool smooth_mask) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -367,12 +360,12 @@ void SCULPT_smooth(Sculpt *sd, data.strength = strength; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_smooth_brush_task_cb_ex, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, nodes.size(), &data, do_smooth_brush_task_cb_ex, &settings); } } -void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, Span nodes) { SculptSession *ss = ob->sculpt; @@ -382,11 +375,11 @@ void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod * middle of the stroke. */ if (ss->cache->bstrength < 0.0f) { /* Invert mode, intensify details. */ - SCULPT_enhance_details_brush(sd, ob, nodes, totnode); + SCULPT_enhance_details_brush(sd, ob, nodes); } else { /* Regular mode, smooth. */ - SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false); + SCULPT_smooth(sd, ob, nodes, ss->cache->bstrength, false); } } @@ -536,7 +529,7 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( BKE_pbvh_vertex_iter_end; } -void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, Span nodes) { Brush *brush = BKE_paint_brush(&sd->paint); @@ -548,11 +541,11 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in data.nodes = nodes; TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); for (int i = 0; i < brush->surface_smooth_iterations; i++) { BLI_task_parallel_range( - 0, totnode, &data, SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex, &settings); + 0, nodes.size(), &data, SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex, &settings); BLI_task_parallel_range( - 0, totnode, &data, SCULPT_do_surface_smooth_brush_displace_task_cb_ex, &settings); + 0, nodes.size(), &data, SCULPT_do_surface_smooth_brush_displace_task_cb_ex, &settings); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.cc b/source/blender/editors/sculpt_paint/sculpt_transform.cc index 820f54c6156..6a1cf586aa4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.cc +++ b/source/blender/editors/sculpt_paint/sculpt_transform.cc @@ -195,9 +195,9 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob) /* Regular transform applies all symmetry passes at once as it is split by symmetry areas * (each vertex can only be transformed once by the transform matrix of its area). */ TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); BLI_task_parallel_range( - 0, ss->filter_cache->totnode, &data, sculpt_transform_task_cb, &settings); + 0, ss->filter_cache->nodes.size(), &data, sculpt_transform_task_cb, &settings); } static void sculpt_elastic_transform_task_cb(void *__restrict userdata, @@ -270,7 +270,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float ss, symm, ss->filter_cache->transform_displacement_mode, data.transform_mats); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); + BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->nodes.size()); /* Elastic transform needs to apply all transform matrices to all vertices and then combine the * displacement proxies as all vertices are modified by all symmetry passes. */ @@ -282,7 +282,7 @@ static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float const int symm_area = SCULPT_get_vertex_symm_area(data.elastic_transform_pivot); copy_m4_m4(data.elastic_transform_mat, data.transform_mats[symm_area]); BLI_task_parallel_range( - 0, ss->filter_cache->totnode, &data, sculpt_elastic_transform_task_cb, &settings); + 0, ss->filter_cache->nodes.size(), &data, sculpt_elastic_transform_task_cb, &settings); } } SCULPT_combine_transform_proxies(sd, ob); @@ -413,9 +413,7 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) } } else { - PBVHNode **nodes; - int totnode; - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); float avg[3]; int total = 0; @@ -423,9 +421,9 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) /* Pivot to unmasked. */ if (mode == SCULPT_PIVOT_POSITION_UNMASKED) { - for (int n = 0; n < totnode; n++) { + for (PBVHNode *node : nodes) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { const float mask = (vd.mask) ? *vd.mask : 0.0f; if (mask < 1.0f) { if (SCULPT_check_vertex_pivot_symmetry(vd.co, ss->pivot_pos, symm)) { @@ -441,9 +439,9 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) else if (mode == SCULPT_PIVOT_POSITION_MASK_BORDER) { const float threshold = 0.2f; - for (int n = 0; n < totnode; n++) { + for (PBVHNode *node : nodes) { PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { const float mask = (vd.mask) ? *vd.mask : 0.0f; if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) { if (SCULPT_check_vertex_pivot_symmetry(vd.co, ss->pivot_pos, symm)) { @@ -460,8 +458,6 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) mul_v3_fl(avg, 1.0f / total); copy_v3_v3(ss->pivot_pos, avg); } - - MEM_SAFE_FREE(nodes); } /* Update the viewport navigation rotation origin. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index f99f04db661..9b9c66540ee 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -659,19 +659,15 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob, } if (unode->type == SCULPT_UNDO_MASK) { - int totnode; - PBVHNode **nodes; - - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range( - 0, totnode, nodes, sculpt_undo_bmesh_restore_generic_task_cb, &settings); - - if (nodes) { - MEM_freeN(nodes); - } + BKE_pbvh_parallel_range_settings(&settings, true, nodes.size()); + BLI_task_parallel_range(0, + nodes.size(), + static_cast(nodes.data()), + sculpt_undo_bmesh_restore_generic_task_cb, + &settings); } else { SCULPT_pbvh_clear(ob); @@ -2153,16 +2149,11 @@ static void sculpt_undo_push_all_grids(Object *object) return; } - PBVHNode **nodes; - int totnodes; - - BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnodes); - for (int i = 0; i < totnodes; i++) { - SculptUndoNode *unode = SCULPT_undo_push_node(object, nodes[i], SCULPT_UNDO_COORDS); + Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, nullptr, nullptr); + for (PBVHNode *node : nodes) { + SculptUndoNode *unode = SCULPT_undo_push_node(object, node, SCULPT_UNDO_COORDS); unode->node = nullptr; } - - MEM_SAFE_FREE(nodes); } void ED_sculpt_undo_push_multires_mesh_begin(bContext *C, const char *str)