From a683d1b0c6f2291e2d3f922a74c647e06fdbdd90 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 26 Dec 2023 09:43:00 -0500 Subject: [PATCH] Cleanup: Use BitVector instead of BLI_bitmap in sculpt code --- .../blenkernel/intern/multires_unsubdivide.cc | 9 +++----- .../editors/sculpt_paint/paint_mask.cc | 9 ++++---- source/blender/editors/sculpt_paint/sculpt.cc | 15 ++++--------- .../sculpt_paint/sculpt_automasking.cc | 1 - .../editors/sculpt_paint/sculpt_boundary.cc | 9 -------- .../editors/sculpt_paint/sculpt_expand.cc | 3 --- .../editors/sculpt_paint/sculpt_geodesic.cc | 21 ++++++++----------- .../editors/sculpt_paint/sculpt_intern.hh | 3 +-- .../editors/sculpt_paint/sculpt_ops.cc | 9 +++----- .../editors/sculpt_paint/sculpt_pose.cc | 16 +++++--------- 10 files changed, 29 insertions(+), 66 deletions(-) diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.cc b/source/blender/blenkernel/intern/multires_unsubdivide.cc index 2bc291cc3d0..3f3bafce9e7 100644 --- a/source/blender/blenkernel/intern/multires_unsubdivide.cc +++ b/source/blender/blenkernel/intern/multires_unsubdivide.cc @@ -164,8 +164,7 @@ static bool is_vertex_diagonal(BMVert *from_v, BMVert *to_v) */ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex) { - bool *visited_verts = static_cast( - MEM_calloc_arrayN(bm->totvert, sizeof(bool), "visited vertices")); + blender::BitVector<> visited_verts(bm->totvert); std::queue queue; /* Add and tag the vertices connected by a diagonal to initial_vertex to the flood fill queue. If @@ -180,7 +179,7 @@ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex int neighbor_vertex_index = BM_elem_index_get(neighbor_v); if (neighbor_v != initial_vertex && is_vertex_diagonal(neighbor_v, initial_vertex)) { queue.push(neighbor_v); - visited_verts[neighbor_vertex_index] = true; + visited_verts[neighbor_vertex_index].set(); BM_elem_flag_set(neighbor_v, BM_ELEM_TAG, true); } } @@ -217,15 +216,13 @@ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex is_vertex_diagonal(neighbor_v, diagonal_v)) { queue.push(neighbor_v); - visited_verts[neighbor_vertex_index] = true; + visited_verts[neighbor_vertex_index].set(); BM_elem_flag_set(neighbor_v, BM_ELEM_TAG, true); } } } } } - - MEM_freeN(visited_verts); } /** diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index 9d71fffc57f..124a163581e 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -534,7 +534,7 @@ struct LassoGestureData { int width; /* 2D bitmap to test if a vertex is affected by the lasso shape. */ - BLI_bitmap *mask_px; + blender::BitVector<> mask_px; }; struct LineGestureData { @@ -668,7 +668,7 @@ static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) int index = (y * lasso->width) + x; int index_end = (y * lasso->width) + x_end; do { - BLI_BITMAP_ENABLE(lasso->mask_px, index); + lasso->mask_px[index].set(); } while (++index != index_end); } @@ -692,7 +692,7 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera const int lasso_width = 1 + sgcontext->lasso.boundbox.xmax - sgcontext->lasso.boundbox.xmin; const int lasso_height = 1 + sgcontext->lasso.boundbox.ymax - sgcontext->lasso.boundbox.ymin; sgcontext->lasso.width = lasso_width; - sgcontext->lasso.mask_px = BLI_BITMAP_NEW(lasso_width * lasso_height, __func__); + sgcontext->lasso.mask_px.resize(lasso_width * lasso_height); BLI_bitmap_draw_2d_poly_v2i_n(sgcontext->lasso.boundbox.xmin, sgcontext->lasso.boundbox.ymin, @@ -847,7 +847,6 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat 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_delete(sgcontext); @@ -964,7 +963,7 @@ static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, co scr_co_s[0] -= lasso->boundbox.xmin; scr_co_s[1] -= lasso->boundbox.ymin; - return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]); + return lasso->mask_px[scr_co_s[1] * lasso->width + scr_co_s[0]].test(); } static bool sculpt_gesture_is_effected(SculptGestureContext *sgcontext, diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index d4a73ae56f4..8a3d73902f8 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -1009,10 +1009,8 @@ namespace blender::ed::sculpt_paint::flood_fill { void init_fill(SculptSession *ss, SculptFloodFill *flood) { - int vertex_count = SCULPT_vertex_count_get(ss); SCULPT_vertex_random_access_ensure(ss); - - flood->visited_verts = BLI_BITMAP_NEW(vertex_count, "visited verts"); + flood->visited_verts.resize(SCULPT_vertex_count_get(ss)); } void add_initial(SculptFloodFill *flood, PBVHVertRef vertex) @@ -1023,7 +1021,7 @@ void add_initial(SculptFloodFill *flood, PBVHVertRef vertex) void add_and_skip_initial(SculptFloodFill *flood, PBVHVertRef vertex) { flood->queue.push(vertex); - BLI_BITMAP_ENABLE(flood->visited_verts, vertex.i); + flood->visited_verts[vertex.i].set(vertex.i); } void add_initial_with_symmetry(Sculpt *sd, @@ -1101,7 +1099,7 @@ void execute(SculptSession *ss, const PBVHVertRef to_v = ni.vertex; int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - if (BLI_BITMAP_TEST(flood->visited_verts, to_v_i)) { + if (flood->visited_verts[to_v_i]) { continue; } @@ -1109,7 +1107,7 @@ void execute(SculptSession *ss, continue; } - BLI_BITMAP_ENABLE(flood->visited_verts, BKE_pbvh_vertex_to_index(ss->pbvh, to_v)); + flood->visited_verts[BKE_pbvh_vertex_to_index(ss->pbvh, to_v)].set(); if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) { flood->queue.push(to_v); @@ -1119,11 +1117,6 @@ void execute(SculptSession *ss, } } -void free_fill(SculptFloodFill *flood) -{ - MEM_SAFE_FREE(flood->visited_verts); -} - } // namespace blender::ed::sculpt_paint::flood_fill /** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index f84fd19c864..8beeadd5f5d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -653,7 +653,6 @@ static void SCULPT_topology_automasking_init(Sculpt *sd, Object *ob) copy_v3_v3(fdata.location, SCULPT_active_vertex_co_get(ss)); flood_fill::execute(ss, &flood, automask_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); } static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob) diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.cc b/source/blender/editors/sculpt_paint/sculpt_boundary.cc index f760d420395..50b8c44a552 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.cc +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.cc @@ -101,7 +101,6 @@ static PBVHVertRef sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss fdata.floodfill_steps = MEM_cnew_array(SCULPT_vertex_count_get(ss), __func__); flood_fill::execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); MEM_freeN(fdata.floodfill_steps); return fdata.boundary_initial_vertex; @@ -264,7 +263,6 @@ static void sculpt_boundary_indices_init(SculptSession *ss, fdata.last_visited_vertex = {BOUNDARY_VERTEX_NONE}; flood_fill::execute(ss, &flood, boundary_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); /* Check if the boundary loops into itself and add the extra preview edge to close the loop. */ if (fdata.last_visited_vertex.i != BOUNDARY_VERTEX_NONE && @@ -311,9 +309,6 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, std::queue current_iteration; std::queue next_iteration; - /* Initialized the first iteration with the vertices already in the boundary. This is propagation - * step 0. */ - BLI_bitmap *visited_verts = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_verts"); for (int i = 0; i < boundary->verts_num; i++) { int index = BKE_pbvh_vertex_to_index(ss->pbvh, boundary->verts[i]); @@ -364,8 +359,6 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, boundary->edit_info[ni.index].original_vertex_i = boundary->edit_info[from_v_i].original_vertex_i; - BLI_BITMAP_ENABLE(visited_verts, ni.index); - if (ni.is_duplicate) { /* Grids duplicates handling. */ boundary->edit_info[ni.index].propagation_steps_num = @@ -418,8 +411,6 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, propagation_steps_num++; } - - MEM_SAFE_FREE(visited_verts); } /* This functions assigns a falloff factor to each one of the SculptBoundaryEditInfo structs based diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index 0d36840f8aa..46fd3b7100d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -503,7 +503,6 @@ static float *sculpt_expand_topology_falloff_create(Sculpt *sd, Object *ob, cons fdata.dists = dists; flood_fill::execute(ss, &flood, expand_topology_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); return dists; } @@ -564,7 +563,6 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd, SCULPT_vertex_normal_get(ss, v, fdata.original_normal); flood_fill::execute(ss, &flood, mask_expand_normal_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); for (int repeat = 0; repeat < blur_steps; repeat++) { for (int i = 0; i < totvert; i++) { @@ -925,7 +923,6 @@ static void sculpt_expand_topology_from_state_boundary(Object *ob, ExpandFloodFillData fdata; fdata.dists = dists; flood_fill::execute(ss, &flood, expand_topology_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); expand_cache->vert_falloff = dists; } diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc index a0b5934736e..940d0eaa65a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc @@ -96,7 +96,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float const VArraySpan hide_poly = *attributes.lookup(".hide_poly", bke::AttrDomain::Face); float *dists = static_cast(MEM_malloc_arrayN(totvert, sizeof(float), __func__)); - BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag"); + BitVector<> edge_tag(totedge); if (ss->epmap.is_empty()) { ss->epmap = bke::mesh::build_edge_to_face_map( @@ -125,13 +125,13 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float /* Masks vertices that are further than limit radius from an initial vertex. As there is no need * to define a distance to them the algorithm can stop earlier by skipping them. */ - BLI_bitmap *affected_vertex = BLI_BITMAP_NEW(totvert, "affected vertex"); + BitVector<> affected_vert(totvert); GSetIterator gs_iter; if (limit_radius == FLT_MAX) { /* In this case, no need to loop through all initial vertices to check distances as they are * all going to be affected. */ - BLI_bitmap_set_all(affected_vertex, true, totvert); + affected_vert.fill(true); } else { /* This is an O(n^2) loop used to limit the geodesic distance calculation to a radius. When @@ -142,7 +142,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float const float *v_co = vert_positions[v]; for (int i = 0; i < totvert; i++) { if (len_squared_v3v3(v_co, vert_positions[i]) <= limit_radius_sq) { - BLI_BITMAP_ENABLE(affected_vertex, i); + affected_vert[i].set(); } } } @@ -152,7 +152,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float for (int i = 0; i < totedge; i++) { const int v1 = edges[i][0]; const int v2 = edges[i][1]; - if (!BLI_BITMAP_TEST(affected_vertex, v1) && !BLI_BITMAP_TEST(affected_vertex, v2)) { + if (!affected_vert[v1] && !affected_vert[v2]) { continue; } if (dists[v1] != FLT_MAX || dists[v2] != FLT_MAX) { @@ -197,12 +197,11 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float ev_other = edges[e_other][0]; } - if (e_other != e && !BLI_BITMAP_TEST(edge_tag, e_other) && + if (e_other != e && !edge_tag[e_other] && (ss->epmap[e_other].is_empty() || dists[ev_other] != FLT_MAX)) { - if (BLI_BITMAP_TEST(affected_vertex, v_other) || - BLI_BITMAP_TEST(affected_vertex, ev_other)) { - BLI_BITMAP_ENABLE(edge_tag, e_other); + if (affected_vert[v_other] || affected_vert[ev_other]) { + edge_tag[e_other].set(); BLI_LINKSTACK_PUSH(queue_next, POINTER_FROM_INT(e_other)); } } @@ -215,7 +214,7 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) { const int e = POINTER_AS_INT(lnk->link); - BLI_BITMAP_DISABLE(edge_tag, e); + edge_tag[e].reset(); } BLI_LINKSTACK_SWAP(queue, queue_next); @@ -224,8 +223,6 @@ static float *geodesic_mesh_create(Object *ob, GSet *initial_verts, const float BLI_LINKSTACK_FREE(queue); BLI_LINKSTACK_FREE(queue_next); - MEM_SAFE_FREE(edge_tag); - MEM_SAFE_FREE(affected_vertex); return dists; } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index bb908c2f141..d35d2ff5f4c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -135,7 +135,7 @@ struct SculptOrigFaceData { /* Flood Fill. */ struct SculptFloodFill { std::queue queue; - BLI_bitmap *visited_verts; + blender::BitVector<> visited_verts; }; enum eBoundaryAutomaskMode { @@ -1249,7 +1249,6 @@ void execute(SculptSession *ss, bool is_duplicate, void *userdata), void *userdata); -void free_fill(SculptFloodFill *flood); } diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index 4a7669a68c7..0733993affd 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -585,7 +585,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float float brush_co[3]; copy_v3_v3(brush_co, SCULPT_active_vertex_co_get(ss)); - BLI_bitmap *visited_verts = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_verts"); + blender::BitVector<> visited_verts(SCULPT_vertex_count_get(ss)); /* Assuming an average of 6 edges per vertex in a triangulated mesh. */ const int max_preview_verts = SCULPT_vertex_count_get(ss) * 3 * 2; @@ -610,10 +610,10 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float totpoints++; ss->preview_vert_list[totpoints] = to_v; totpoints++; - if (BLI_BITMAP_TEST(visited_verts, to_v_i)) { + if (visited_verts[to_v_i]) { continue; } - BLI_BITMAP_ENABLE(visited_verts, to_v_i); + visited_verts[to_v_i].set(); const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v); if (len_squared_v3v3(brush_co, co) < radius * radius) { non_visited_verts.push(to_v); @@ -623,8 +623,6 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); } - MEM_freeN(visited_verts); - ss->preview_vert_count = totpoints; } @@ -826,7 +824,6 @@ static void sculpt_mask_by_color_contiguous(Object *object, copy_v3_v3(ffd.initial_color, color); flood_fill::execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill, &ffd); - flood_fill::free_fill(&flood); Vector nodes = blender::bke::pbvh::search_gather(ss->pbvh, {}); const SculptMaskWriteInfo mask_write = SCULPT_mask_get_for_write(ss); diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.cc b/source/blender/editors/sculpt_paint/sculpt_pose.cc index 4a669366cf2..485115a59bd 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.cc +++ b/source/blender/editors/sculpt_paint/sculpt_pose.cc @@ -361,7 +361,7 @@ struct PoseFloodFillData { GSet *visited_face_sets; /* In face sets origin mode, each vertex can only be assigned to one face set. */ - BLI_bitmap *is_weighted; + MutableBoundedBitSpan is_weighted; bool is_first_iteration; @@ -435,7 +435,7 @@ static bool pose_face_sets_floodfill_cb( if (data->current_face_set == SCULPT_FACE_SET_NONE) { data->pose_factor[index] = 1.0f; - BLI_BITMAP_ENABLE(data->is_weighted, index); + data->is_weighted[index].set(); if (sculpt_pose_brush_is_vertex_inside_brush_radius( co, data->pose_initial_co, data->radius, data->symm)) @@ -469,9 +469,9 @@ static bool pose_face_sets_floodfill_cb( return visit_next; } - if (!BLI_BITMAP_TEST(data->is_weighted, index)) { + if (!data->is_weighted[index]) { data->pose_factor[index] = 1.0f; - BLI_BITMAP_ENABLE(data->is_weighted, index); + data->is_weighted[index].set(); visit_next = true; } @@ -543,7 +543,6 @@ void calc_pose_data(Sculpt *sd, copy_v3_v3(fdata.pose_initial_co, initial_location); copy_v3_v3(fdata.fallback_floodfill_origin, initial_location); flood_fill::execute(ss, &flood, pose_topology_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); if (fdata.tot_co > 0) { mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co)); @@ -728,7 +727,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( GSet *visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", ik_chain->tot_segments); - BLI_bitmap *is_weighted = BLI_BITMAP_NEW(totvert, "weighted"); + BitVector<> is_weighted(totvert); int current_face_set = SCULPT_FACE_SET_NONE; int prev_face_set = SCULPT_FACE_SET_NONE; @@ -760,7 +759,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( zero_v3(fdata.fallback_origin); copy_v3_v3(fdata.pose_initial_co, SCULPT_vertex_co_get(ss, current_vertex)); flood_fill::execute(ss, &flood, pose_face_sets_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); if (fdata.tot_co > 0) { mul_v3_fl(fdata.pose_origin, 1.0f / float(fdata.tot_co)); @@ -783,8 +781,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( pose_ik_chain_origin_heads_init(ik_chain, SCULPT_active_vertex_co_get(ss)); - MEM_SAFE_FREE(is_weighted); - return ik_chain; } @@ -864,7 +860,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( fdata.masked_face_set_it = 0; fdata.visited_face_sets = BLI_gset_int_new_ex("visited_face_sets", 3); flood_fill::execute(ss, &flood, pose_face_sets_fk_find_masked_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); BLI_gset_free(fdata.visited_face_sets, nullptr); int origin_count = 0; @@ -920,7 +915,6 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( flood_fill::add_active(sd, ob, ss, &flood, radius); fdata.fk_weights = ik_chain->segments[0].weights; flood_fill::execute(ss, &flood, pose_face_sets_fk_set_weights_floodfill_cb, &fdata); - flood_fill::free_fill(&flood); pose_ik_chain_origin_heads_init(ik_chain, ik_chain->segments[0].head); return ik_chain;