From 75db4c082ba7bd3d311bd0f65b75934109199ee6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 6 Feb 2023 13:24:40 -0500 Subject: [PATCH] Cleanup: Use BitVector instead of BLI_bitmap for subsurf face dot tags For better type safety and more automatic memory management. --- source/blender/blenkernel/BKE_mesh_types.h | 8 ++++--- source/blender/blenkernel/intern/mesh.cc | 8 +++---- .../blenkernel/intern/mesh_iterators.cc | 7 +++--- .../blender/blenkernel/intern/mesh_runtime.cc | 5 ++--- .../blender/blenkernel/intern/subdiv_mesh.cc | 9 ++++---- source/blender/blenlib/BLI_bit_vector.hh | 22 +++++++++++++++++++ .../draw/intern/draw_cache_extract_mesh.cc | 3 ++- .../extract_mesh_ibo_edituv.cc | 4 ++-- .../mesh_extractors/extract_mesh_ibo_fdots.cc | 4 ++-- .../extract_mesh_vbo_fdots_pos.cc | 4 ++-- .../extract_mesh_vbo_fdots_uv.cc | 4 ++-- .../editors/space_view3d/view3d_iterators.cc | 6 ++--- 12 files changed, 53 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index 0e0bced37ec..c9992a5e3d7 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -25,6 +25,7 @@ struct BVHCache; struct EditMeshData; +struct Mesh; struct MLoopTri; struct ShrinkwrapBoundaryData; struct SubdivCCG; @@ -167,10 +168,11 @@ struct MeshRuntime { SharedCache loose_edges_cache; /** - * A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the - * subdivision surface modifier and used by drawing code instead of polygon center face dots. + * A bit vector the size of the number of vertices, set to true for the center vertices of + * subdivided polygons. The values are set by the subdivision surface modifier and used by + * drawing code instead of polygon center face dots. Otherwise this will be empty. */ - uint32_t *subsurf_face_dot_tags = nullptr; + BitVector<> subsurf_face_dot_tags; MeshRuntime() = default; ~MeshRuntime(); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index dfdad20cc48..f588bfb1326 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -107,10 +107,10 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int mesh_dst->runtime->wrapper_type_finalize = mesh_src->runtime->wrapper_type_finalize; mesh_dst->runtime->subsurf_runtime_data = mesh_src->runtime->subsurf_runtime_data; mesh_dst->runtime->cd_mask_extra = mesh_src->runtime->cd_mask_extra; - /* Copy face dot tags, since meshes may be duplicated after a subsurf modifier - * or node, but we still need to be able to draw face center vertices. */ - mesh_dst->runtime->subsurf_face_dot_tags = static_cast( - MEM_dupallocN(mesh_src->runtime->subsurf_face_dot_tags)); + /* Copy face dot tags, since meshes may be duplicated after a subsurf modifier or node, but we + * still need to be able to draw face center vertices. The tags may be cleared explicitly when + * the topology is changed. */ + mesh_dst->runtime->subsurf_face_dot_tags = mesh_src->runtime->subsurf_face_dot_tags; if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) { /* This is a direct copy of a main mesh, so for now it has the same topology. */ mesh_dst->runtime->deformed_only = true; diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index b1aa4dcec53..45ad8f2b626 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -316,8 +316,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( BKE_mesh_vertex_normals_ensure(mesh) : nullptr; const int *index = static_cast(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX)); - const BLI_bitmap *facedot_tags = mesh->runtime->subsurf_face_dot_tags; - BLI_assert(facedot_tags != nullptr); + const blender::BitVector<> &facedot_tags = mesh->runtime->subsurf_face_dot_tags; if (index) { for (int i = 0; i < mesh->totpoly; i++, mp++) { @@ -327,7 +326,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( } ml = &loops[mp->loopstart]; for (int j = 0; j < mp->totloop; j++, ml++) { - if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { + if (facedot_tags[ml->v]) { func(userData, orig, positions[ml->v], @@ -340,7 +339,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( for (int i = 0; i < mesh->totpoly; i++, mp++) { ml = &loops[mp->loopstart]; for (int j = 0; j < mp->totloop; j++, ml++) { - if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { + if (facedot_tags[ml->v]) { func(userData, i, positions[ml->v], diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 9509eea39e0..3c64d7f3742 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -105,7 +105,6 @@ MeshRuntime::~MeshRuntime() if (this->shrinkwrap_data) { BKE_shrinkwrap_boundary_data_free(this->shrinkwrap_data); } - MEM_SAFE_FREE(this->subsurf_face_dot_tags); } } // namespace blender::bke @@ -230,10 +229,10 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh) mesh->runtime->bounds_cache.tag_dirty(); mesh->runtime->loose_edges_cache.tag_dirty(); mesh->runtime->looptris_cache.tag_dirty(); + mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); if (mesh->runtime->shrinkwrap_data) { BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); } - MEM_SAFE_FREE(mesh->runtime->subsurf_face_dot_tags); } void BKE_mesh_tag_edges_split(struct Mesh *mesh) @@ -245,10 +244,10 @@ void BKE_mesh_tag_edges_split(struct Mesh *mesh) free_normals(*mesh->runtime); free_subdiv_ccg(*mesh->runtime); mesh->runtime->loose_edges_cache.tag_dirty(); + mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); if (mesh->runtime->shrinkwrap_data) { BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); } - MEM_SAFE_FREE(mesh->runtime->subsurf_face_dot_tags); } void BKE_mesh_tag_coords_changed(Mesh *mesh) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index e0ca6a12c4e..0f735f06b42 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -534,9 +534,8 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask); subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context); subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices); - MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags); - subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices, - __func__); + subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.clear(); + subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags.resize(num_vertices); return true; } @@ -598,7 +597,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext /* Evaluate undeformed texture coordinate. */ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index); /* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */ - BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index); + ctx->subdiv_mesh->runtime->subsurf_face_dot_tags[subdiv_vertex_index].reset(); } static void evaluate_vertex_and_apply_displacement_interpolate( @@ -752,7 +751,7 @@ static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly, Mesh *subdiv_mesh) { if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) { - BLI_BITMAP_ENABLE(subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index); + subdiv_mesh->runtime->subsurf_face_dot_tags[subdiv_vertex_index].set(); } } diff --git a/source/blender/blenlib/BLI_bit_vector.hh b/source/blender/blenlib/BLI_bit_vector.hh index eddfbaf4528..bad371fc88a 100644 --- a/source/blender/blenlib/BLI_bit_vector.hh +++ b/source/blender/blenlib/BLI_bit_vector.hh @@ -478,6 +478,28 @@ class BitVector { this->realloc_to_at_least(new_capacity_in_bits); } + /** + * Reset the size of the vector to zero elements, but keep the same memory capacity to be + * refilled again. + */ + void clear() + { + size_in_bits_ = 0; + } + + /** + * Free memory and reset the vector to zero elements. + */ + void clear_and_shrink() + { + size_in_bits_ = 0; + capacity_in_bits_ = 0; + if (!this->is_inline()) { + allocator_.deallocate(data_); + } + data_ = inline_buffer_; + } + private: void ensure_space_for_one() { diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index ab89436f636..5626b782802 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -684,7 +684,8 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, MeshRenderData *mr = mesh_render_data_create( object, me, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts); mr->use_hide = use_hide; - mr->use_subsurf_fdots = mr->me && mr->me->runtime->subsurf_face_dot_tags != nullptr; + mr->use_subsurf_fdots = mr->me && + mr->me->runtime->subsurf_face_dot_tags.size() == mr->me->totvert; mr->use_final_mesh = do_final; #ifdef DEBUG_TIME diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc index e40503a9707..233241ad776 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc @@ -557,7 +557,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr, const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false; if (mr->use_subsurf_fdots) { - const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; @@ -565,7 +565,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr, const MLoop *ml = &mloop[ml_index]; const bool real_fdot = !mr->p_origindex || (mr->p_origindex[mp_index] != ORIGINDEX_NONE); - const bool subd_fdot = BLI_BITMAP_TEST(facedot_tags, ml->v); + const bool subd_fdot = facedot_tags[ml->v]; edituv_facedot_add(data, mp_hidden || !real_fdot || !subd_fdot, mp_select, mp_index); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc index 1b552b01d6b..bd04f6dbb03 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc @@ -46,13 +46,13 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr, GPUIndexBufBuilder *elb = static_cast(_userdata); if (mr->use_subsurf_fdots) { - const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { const MLoop *ml = &mloop[ml_index]; - if (BLI_BITMAP_TEST(facedot_tags, ml->v) && !hidden) { + if (facedot_tags[ml->v] && !hidden) { GPU_indexbuf_set_point_vert(elb, mp_index, mp_index); return; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc index f5c470e7a75..b9f2917d0fe 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc @@ -76,13 +76,13 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, zero_v3(co); const MLoop *mloop = mr->mloop; - const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const int ml_index_end = mp->loopstart + mp->totloop; for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { const MLoop *ml = &mloop[ml_index]; if (mr->use_subsurf_fdots) { - if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { + if (facedot_tags[ml->v]) { copy_v3_v3(center[mp_index], mr->vert_positions[ml->v]); break; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc index c8d4144f38c..1ed6dc26b6f 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc @@ -74,14 +74,14 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr, void *_data) { MeshExtract_FdotUV_Data *data = static_cast(_data); - const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; + const BitVector<> &facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { const MLoop *ml = &mloop[ml_index]; if (mr->use_subsurf_fdots) { - if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { + if (facedot_tags[ml->v]) { copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index]); } } diff --git a/source/blender/editors/space_view3d/view3d_iterators.cc b/source/blender/editors/space_view3d/view3d_iterators.cc index f35fbf5c944..09ff3fa6574 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.cc +++ b/source/blender/editors/space_view3d/view3d_iterators.cc @@ -577,12 +577,12 @@ void mesh_foreachScreenFace( BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE); - if (me->runtime->subsurf_face_dot_tags != nullptr) { - BKE_mesh_foreach_mapped_subdiv_face_center( + if (me->runtime->subsurf_face_dot_tags.size() == me->totvert) { + BKE_mesh_foreach_mapped_face_center( me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); } else { - BKE_mesh_foreach_mapped_face_center( + BKE_mesh_foreach_mapped_subdiv_face_center( me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); } }