From 695e626d3ff5e9413e121ba07bf96a6aedd8bde5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 4 Dec 2023 15:22:00 -0500 Subject: [PATCH] Cleanup: Store more mesh runtime data with unique_ptr Convert shrinkwrap data arrays to use C++ arrays and BitVector, use references in "EditMeshData" code, and store both structs with `std::unique_ptr` instead of a raw allocation. --- .../blender/blenkernel/BKE_editmesh_cache.hh | 8 +-- source/blender/blenkernel/BKE_mesh_runtime.hh | 2 +- source/blender/blenkernel/BKE_mesh_types.hh | 4 +- source/blender/blenkernel/BKE_shrinkwrap.hh | 13 ++-- .../blender/blenkernel/intern/DerivedMesh.cc | 6 +- .../blenkernel/intern/editmesh_cache.cc | 46 +++++++-------- source/blender/blenkernel/intern/mesh.cc | 2 +- .../blenkernel/intern/mesh_iterators.cc | 6 +- .../blender/blenkernel/intern/mesh_runtime.cc | 24 ++------ .../blender/blenkernel/intern/mesh_wrapper.cc | 23 ++++---- source/blender/blenkernel/intern/modifier.cc | 6 +- .../blender/blenkernel/intern/object_dupli.cc | 4 +- .../blender/blenkernel/intern/shrinkwrap.cc | 59 +++++++------------ .../draw_cache_extract_mesh_render_data.cc | 6 +- .../extract_mesh_vbo_mesh_analysis.cc | 2 +- 15 files changed, 89 insertions(+), 122 deletions(-) diff --git a/source/blender/blenkernel/BKE_editmesh_cache.hh b/source/blender/blenkernel/BKE_editmesh_cache.hh index 4a0fbfa33f5..e6c9367fb04 100644 --- a/source/blender/blenkernel/BKE_editmesh_cache.hh +++ b/source/blender/blenkernel/BKE_editmesh_cache.hh @@ -29,10 +29,10 @@ struct EditMeshData { } // namespace blender::bke -void BKE_editmesh_cache_ensure_face_normals(BMEditMesh *em, blender::bke::EditMeshData *emd); -void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, blender::bke::EditMeshData *emd); +void BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMeshData &emd); +void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMeshData &emd); -void BKE_editmesh_cache_ensure_face_centers(BMEditMesh *em, blender::bke::EditMeshData *emd); +void BKE_editmesh_cache_ensure_face_centers(BMEditMesh &em, blender::bke::EditMeshData &emd); std::optional> BKE_editmesh_cache_calc_minmax( - const BMEditMesh *em, const blender::bke::EditMeshData *emd); + const BMEditMesh &em, const blender::bke::EditMeshData &emd); diff --git a/source/blender/blenkernel/BKE_mesh_runtime.hh b/source/blender/blenkernel/BKE_mesh_runtime.hh index e2da362b739..06830ae9dfd 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.hh +++ b/source/blender/blenkernel/BKE_mesh_runtime.hh @@ -23,7 +23,7 @@ struct Scene; /** Return the number of derived triangles (looptris). */ int BKE_mesh_runtime_looptri_len(const Mesh *mesh); -bool BKE_mesh_runtime_ensure_edit_data(Mesh *mesh); +void BKE_mesh_runtime_ensure_edit_data(Mesh *mesh); /** * Clear and free any derived caches associated with the mesh geometry data. Examples include BVH diff --git a/source/blender/blenkernel/BKE_mesh_types.hh b/source/blender/blenkernel/BKE_mesh_types.hh index bfce3516bb1..dba8bc32d53 100644 --- a/source/blender/blenkernel/BKE_mesh_types.hh +++ b/source/blender/blenkernel/BKE_mesh_types.hh @@ -117,7 +117,7 @@ struct MeshRuntime { * Lazily initialized SoA data from the #edit_mesh field in #Mesh. Used when the mesh is a BMesh * wrapper (#ME_WRAPPER_TYPE_BMESH). */ - EditMeshData *edit_data = nullptr; + std::unique_ptr edit_data; /** * Data used to efficiently draw the mesh in the viewport, especially useful when @@ -134,7 +134,7 @@ struct MeshRuntime { BVHCache *bvh_cache = nullptr; /** Cache of non-manifold boundary data for Shrink-wrap Target Project. */ - ShrinkwrapBoundaryData *shrinkwrap_data = nullptr; + std::unique_ptr shrinkwrap_data; /** Needed in case we need to lazily initialize the mesh. */ CustomData_MeshMasks cd_mask_extra = {}; diff --git a/source/blender/blenkernel/BKE_shrinkwrap.hh b/source/blender/blenkernel/BKE_shrinkwrap.hh index 5073914e281..28700176696 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.hh +++ b/source/blender/blenkernel/BKE_shrinkwrap.hh @@ -9,8 +9,9 @@ /* Shrinkwrap stuff */ #include "BKE_bvhutils.hh" -#include "BLI_bitmap.h" +#include "BLI_array.hh" +#include "BLI_bit_vector.hh" #include "BLI_math_vector_types.hh" #include "BLI_offset_indices.hh" #include "BLI_span.hh" @@ -48,23 +49,21 @@ struct ShrinkwrapBoundaryVertData { struct ShrinkwrapBoundaryData { /* True if the edge belongs to exactly one face. */ - const BLI_bitmap *edge_is_boundary; + blender::BitVector<> edge_is_boundary; /* True if the looptri has any boundary edges. */ - const BLI_bitmap *looptri_has_boundary; + blender::BitVector<> looptri_has_boundary; /* Mapping from vertex index to boundary vertex index, or -1. * Used for compact storage of data about boundary vertices. */ - const int *vert_boundary_id; - unsigned int num_boundary_verts; + blender::Array vert_boundary_id; /* Direction data about boundary vertices. */ - const ShrinkwrapBoundaryVertData *boundary_verts; + blender::Array boundary_verts; }; /** * Free boundary data for target project. */ -void BKE_shrinkwrap_boundary_data_free(ShrinkwrapBoundaryData *data); void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh); /* Information about a mesh and BVH tree. */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index c8533d0dc5e..143d3c902e3 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1035,9 +1035,9 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final) case ME_WRAPPER_TYPE_MDATA: break; case ME_WRAPPER_TYPE_BMESH: { - BMEditMesh *em = mesh_final->edit_mesh; - blender::bke::EditMeshData *emd = mesh_final->runtime->edit_data; - if (!emd->vertexCos.is_empty()) { + BMEditMesh &em = *mesh_final->edit_mesh; + blender::bke::EditMeshData &emd = *mesh_final->runtime->edit_data; + if (!emd.vertexCos.is_empty()) { BKE_editmesh_cache_ensure_vert_normals(em, emd); BKE_editmesh_cache_ensure_face_normals(em, emd); } diff --git a/source/blender/blenkernel/intern/editmesh_cache.cc b/source/blender/blenkernel/intern/editmesh_cache.cc index 5943c8aeba0..682c8b3f317 100644 --- a/source/blender/blenkernel/intern/editmesh_cache.cc +++ b/source/blender/blenkernel/intern/editmesh_cache.cc @@ -23,14 +23,14 @@ /** \name Ensure Data (derived from coords) * \{ */ -void BKE_editmesh_cache_ensure_face_normals(BMEditMesh *em, blender::bke::EditMeshData *emd) +void BKE_editmesh_cache_ensure_face_normals(BMEditMesh &em, blender::bke::EditMeshData &emd) { - if (emd->vertexCos.is_empty() || !emd->faceNos.is_empty()) { + if (emd.vertexCos.is_empty() || !emd.faceNos.is_empty()) { return; } - BMesh *bm = em->bm; + BMesh *bm = em.bm; - emd->faceNos.reinitialize(bm->totface); + emd.faceNos.reinitialize(bm->totface); BM_mesh_elem_index_ensure(bm, BM_VERT); BMFace *efa; @@ -39,52 +39,52 @@ void BKE_editmesh_cache_ensure_face_normals(BMEditMesh *em, blender::bke::EditMe BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { BM_elem_index_set(efa, i); /* set_inline */ BM_face_calc_normal_vcos( - bm, efa, emd->faceNos[i], reinterpret_cast(emd->vertexCos.data())); + bm, efa, emd.faceNos[i], reinterpret_cast(emd.vertexCos.data())); } bm->elem_index_dirty &= ~BM_FACE; } -void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh *em, blender::bke::EditMeshData *emd) +void BKE_editmesh_cache_ensure_vert_normals(BMEditMesh &em, blender::bke::EditMeshData &emd) { - if (emd->vertexCos.is_empty() || !emd->vertexNos.is_empty()) { + if (emd.vertexCos.is_empty() || !emd.vertexNos.is_empty()) { return; } - BMesh *bm = em->bm; + BMesh *bm = em.bm; /* Calculate vertex normals from face normals. */ BKE_editmesh_cache_ensure_face_normals(em, emd); - emd->vertexNos.reinitialize(bm->totvert); + emd.vertexNos.reinitialize(bm->totvert); BM_mesh_elem_index_ensure(bm, BM_FACE); BM_verts_calc_normal_vcos(bm, - reinterpret_cast(emd->faceNos.data()), - reinterpret_cast(emd->vertexCos.data()), - reinterpret_cast(emd->vertexNos.data())); + reinterpret_cast(emd.faceNos.data()), + reinterpret_cast(emd.vertexCos.data()), + reinterpret_cast(emd.vertexNos.data())); } -void BKE_editmesh_cache_ensure_face_centers(BMEditMesh *em, blender::bke::EditMeshData *emd) +void BKE_editmesh_cache_ensure_face_centers(BMEditMesh &em, blender::bke::EditMeshData &emd) { - if (!emd->faceCos.is_empty()) { + if (!emd.faceCos.is_empty()) { return; } - BMesh *bm = em->bm; + BMesh *bm = em.bm; - emd->faceCos.reinitialize(bm->totface); + emd.faceCos.reinitialize(bm->totface); BMFace *efa; BMIter fiter; int i; - if (emd->vertexCos.is_empty()) { + if (emd.vertexCos.is_empty()) { BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { - BM_face_calc_center_median(efa, emd->faceCos[i]); + BM_face_calc_center_median(efa, emd.faceCos[i]); } } else { BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { BM_face_calc_center_median_vcos( - bm, efa, emd->faceCos[i], reinterpret_cast(emd->vertexCos.data())); + bm, efa, emd.faceCos[i], reinterpret_cast(emd.vertexCos.data())); } } } @@ -96,15 +96,15 @@ void BKE_editmesh_cache_ensure_face_centers(BMEditMesh *em, blender::bke::EditMe * \{ */ std::optional> BKE_editmesh_cache_calc_minmax( - const BMEditMesh *em, const blender::bke::EditMeshData *emd) + const BMEditMesh &em, const blender::bke::EditMeshData &emd) { using namespace blender; - BMesh *bm = em->bm; + BMesh *bm = em.bm; if (bm->totvert == 0) { return std::nullopt; } - if (emd->vertexCos.is_empty()) { + if (emd.vertexCos.is_empty()) { BMVert *eve; BMIter iter; float3 min(std::numeric_limits::max()); @@ -115,7 +115,7 @@ std::optional> BKE_editmesh_cache_calc_minmax( return Bounds{min, max}; } - return bounds::min_max(emd->vertexCos.as_span()); + return bounds::min_max(emd.vertexCos.as_span()); } /** \} */ diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 63430b1a296..06dd1038cdb 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1090,7 +1090,7 @@ std::optional> Mesh::bounds_min_max() const this->runtime->bounds_cache.ensure([&](Bounds &r_bounds) { switch (this->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: - r_bounds = *BKE_editmesh_cache_calc_minmax(this->edit_mesh, this->runtime->edit_data); + r_bounds = *BKE_editmesh_cache_calc_minmax(*this->edit_mesh, *this->runtime->edit_data); break; case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index 4fa4a25ffaf..af42f8bda9d 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -48,7 +48,7 @@ void BKE_mesh_foreach_mapped_vert( const blender::Span positions = mesh->runtime->edit_data->vertexCos; blender::Span vert_normals; if (flag & MESH_FOREACH_USE_NORMAL) { - BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime->edit_data); + BKE_editmesh_cache_ensure_vert_normals(*em, *mesh->runtime->edit_data); vert_normals = mesh->runtime->edit_data->vertexNos; } BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { @@ -245,11 +245,11 @@ void BKE_mesh_foreach_mapped_face_center( BMIter iter; int i; - BKE_editmesh_cache_ensure_face_centers(em, mesh->runtime->edit_data); + BKE_editmesh_cache_ensure_face_centers(*em, *mesh->runtime->edit_data); face_centers = mesh->runtime->edit_data->faceCos; /* always set */ if (flag & MESH_FOREACH_USE_NORMAL) { - BKE_editmesh_cache_ensure_face_normals(em, mesh->runtime->edit_data); + BKE_editmesh_cache_ensure_face_normals(*em, *mesh->runtime->edit_data); face_normals = mesh->runtime->edit_data->faceNos; /* maybe nullptr */ } diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 96a2f0d395f..1048deffc89 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -70,9 +70,6 @@ MeshRuntime::~MeshRuntime() free_mesh_eval(*this); free_bvh_cache(*this); free_batch_cache(*this); - if (this->shrinkwrap_data) { - BKE_shrinkwrap_boundary_data_free(this->shrinkwrap_data); - } } static int reset_bits_and_count(MutableBitSpan bits, const Span indices_to_reset) @@ -282,13 +279,11 @@ void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri, } } -bool BKE_mesh_runtime_ensure_edit_data(Mesh *mesh) +void BKE_mesh_runtime_ensure_edit_data(Mesh *mesh) { - if (mesh->runtime->edit_data != nullptr) { - return false; + if (!mesh->runtime->edit_data) { + mesh->runtime->edit_data = std::make_unique(); } - mesh->runtime->edit_data = MEM_new(__func__); - return true; } void BKE_mesh_runtime_clear_cache(Mesh *mesh) @@ -296,8 +291,7 @@ void BKE_mesh_runtime_clear_cache(Mesh *mesh) using namespace blender::bke; free_mesh_eval(*mesh->runtime); free_batch_cache(*mesh->runtime); - MEM_delete(mesh->runtime->edit_data); - mesh->runtime->edit_data = nullptr; + mesh->runtime->edit_data.reset(); BKE_mesh_runtime_clear_geometry(mesh); } @@ -320,10 +314,7 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh) mesh->runtime->looptri_faces_cache.tag_dirty(); mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink(); - if (mesh->runtime->shrinkwrap_data) { - BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); - mesh->runtime->shrinkwrap_data = nullptr; - } + mesh->runtime->shrinkwrap_data.reset(); mesh->flag &= ~ME_NO_OVERLAPPING_TOPOLOGY; } @@ -353,10 +344,7 @@ void BKE_mesh_tag_edges_split(Mesh *mesh) } mesh->runtime->subsurf_face_dot_tags.clear_and_shrink(); mesh->runtime->subsurf_optimal_display_edges.clear_and_shrink(); - if (mesh->runtime->shrinkwrap_data) { - BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); - mesh->runtime->shrinkwrap_data = nullptr; - } + mesh->runtime->shrinkwrap_data.reset(); } void BKE_mesh_tag_sharpness_changed(Mesh *mesh) diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 27b367e0ce8..3b910f83889 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -125,9 +125,9 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me) * be wrong, but it's not harmful. */ BKE_mesh_ensure_default_orig_index_customdata_no_check(me); - blender::bke::EditMeshData *edit_data = me->runtime->edit_data; - if (!edit_data->vertexCos.is_empty()) { - me->vert_positions_for_write().copy_from(edit_data->vertexCos); + blender::bke::EditMeshData &edit_data = *me->runtime->edit_data; + if (!edit_data.vertexCos.is_empty()) { + me->vert_positions_for_write().copy_from(edit_data.vertexCos); me->runtime->is_original_bmesh = false; } @@ -135,8 +135,7 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me) BKE_mesh_wrapper_deferred_finalize_mdata(me); } - MEM_delete(me->runtime->edit_data); - me->runtime->edit_data = nullptr; + me->runtime->edit_data.reset(); break; } } @@ -170,7 +169,7 @@ const float (*BKE_mesh_wrapper_face_normals(Mesh *mesh))[3] { switch (mesh->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: - BKE_editmesh_cache_ensure_face_normals(mesh->edit_mesh, mesh->runtime->edit_data); + BKE_editmesh_cache_ensure_face_normals(*mesh->edit_mesh, *mesh->runtime->edit_data); if (mesh->runtime->edit_data->faceNos.is_empty()) { return nullptr; } @@ -204,9 +203,9 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, blender::MutableSpanruntime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: { BMesh *bm = me->edit_mesh->bm; - blender::bke::EditMeshData *edit_data = me->runtime->edit_data; - if (!edit_data->vertexCos.is_empty()) { - positions.copy_from(edit_data->vertexCos); + const blender::bke::EditMeshData &edit_data = *me->runtime->edit_data; + if (!edit_data.vertexCos.is_empty()) { + positions.copy_from(edit_data.vertexCos); } else { BMIter iter; @@ -236,10 +235,10 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, case ME_WRAPPER_TYPE_BMESH: { BMesh *bm = me->edit_mesh->bm; BLI_assert(vert_coords_len == bm->totvert); - const blender::bke::EditMeshData *edit_data = me->runtime->edit_data; - if (!edit_data->vertexCos.is_empty()) { + const blender::bke::EditMeshData &edit_data = *me->runtime->edit_data; + if (!edit_data.vertexCos.is_empty()) { for (int i = 0; i < vert_coords_len; i++) { - mul_v3_m4v3(vert_coords[i], mat, edit_data->vertexCos[i]); + mul_v3_m4v3(vert_coords[i], mat, edit_data.vertexCos[i]); } } else { diff --git a/source/blender/blenkernel/intern/modifier.cc b/source/blender/blenkernel/intern/modifier.cc index 6738c85928d..829178e6bc2 100644 --- a/source/blender/blenkernel/intern/modifier.cc +++ b/source/blender/blenkernel/intern/modifier.cc @@ -965,11 +965,11 @@ static void modwrap_dependsOnNormals(Mesh *me) { switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: { - blender::bke::EditMeshData *edit_data = me->runtime->edit_data; - if (!edit_data->vertexCos.is_empty()) { + blender::bke::EditMeshData &edit_data = *me->runtime->edit_data; + if (!edit_data.vertexCos.is_empty()) { /* Note that 'ensure' is acceptable here since these values aren't modified in-place. * If that changes we'll need to recalculate. */ - BKE_editmesh_cache_ensure_vert_normals(me->edit_mesh, edit_data); + BKE_editmesh_cache_ensure_vert_normals(*me->edit_mesh, edit_data); } else { BM_mesh_normals_update(me->edit_mesh->bm); diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 9aa1cc6a338..9c767f9f57f 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -478,7 +478,7 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob, * We could change this but it matches 2.7x behavior. */ me_eval = BKE_object_get_editmesh_eval_cage(ob); if ((me_eval == nullptr) || (me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) { - blender::bke::EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr; + blender::bke::EditMeshData *emd = me_eval ? me_eval->runtime->edit_data.get() : nullptr; /* Only assign edit-mesh in the case we can't use `me_eval`. */ *r_em = em; @@ -487,7 +487,7 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob, if ((emd != nullptr) && !emd->vertexCos.is_empty()) { *r_vert_coords = reinterpret_cast(emd->vertexCos.data()); if (r_vert_normals != nullptr) { - BKE_editmesh_cache_ensure_vert_normals(em, emd); + BKE_editmesh_cache_ensure_vert_normals(*em, *emd); *r_vert_normals = reinterpret_cast(emd->vertexNos.data()); } } diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index f43c403e540..455bd6d62f5 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -148,7 +148,7 @@ bool BKE_shrinkwrap_init_tree( } if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { - data->boundary = mesh->runtime->shrinkwrap_data; + data->boundary = mesh->runtime->shrinkwrap_data.get(); } return true; @@ -159,16 +159,6 @@ void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data) free_bvhtree_from_mesh(&data->treeData); } -void BKE_shrinkwrap_boundary_data_free(ShrinkwrapBoundaryData *data) -{ - MEM_freeN((void *)data->edge_is_boundary); - MEM_freeN((void *)data->looptri_has_boundary); - MEM_freeN((void *)data->vert_boundary_id); - MEM_freeN((void *)data->boundary_verts); - - MEM_freeN(data); -} - /* Accumulate edge for average boundary edge direction. */ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata, signed char *status, @@ -193,7 +183,7 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata, status[index] = (status[index] == 0) ? side : -1; } -static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) +static std::unique_ptr shrinkwrap_build_boundary_data(Mesh *mesh) { using namespace blender; const blender::Span positions = mesh->vert_positions(); @@ -214,36 +204,33 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) } /* Build the boundary edge bitmask. */ - BLI_bitmap *edge_is_boundary = BLI_BITMAP_NEW(mesh->totedge, - "ShrinkwrapBoundaryData::edge_is_boundary"); + blender::BitVector<> edge_is_boundary(mesh->totedge, false); uint num_boundary_edges = 0; for (int i = 0; i < mesh->totedge; i++) { edge_mode[i] = (edge_mode[i] == 1); if (edge_mode[i]) { - BLI_BITMAP_ENABLE(edge_is_boundary, i); + edge_is_boundary[i].set(); num_boundary_edges++; } } /* If no boundary, return nullptr. */ if (num_boundary_edges == 0) { - MEM_freeN(edge_is_boundary); MEM_freeN(edge_mode); - return nullptr; + return {}; } /* Allocate the data object. */ - ShrinkwrapBoundaryData *data = MEM_cnew(__func__); + std::unique_ptr data = std::make_unique(); - data->edge_is_boundary = edge_is_boundary; + data->edge_is_boundary = std::move(edge_is_boundary); /* Build the boundary looptri bitmask. */ const blender::Span looptris = mesh->looptris(); - BLI_bitmap *looptri_has_boundary = BLI_BITMAP_NEW(looptris.size(), - "ShrinkwrapBoundaryData::looptri_is_boundary"); + blender::BitVector<> looptri_has_boundary(looptris.size(), false); for (const int64_t i : looptris.index_range()) { const int3 real_edges = bke::mesh::looptri_get_real_edges( @@ -251,17 +238,16 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) for (int j = 0; j < 3; j++) { if (real_edges[j] >= 0 && edge_mode[real_edges[j]]) { - BLI_BITMAP_ENABLE(looptri_has_boundary, i); + looptri_has_boundary[i].set(); break; } } } - data->looptri_has_boundary = looptri_has_boundary; + data->looptri_has_boundary = std::move(looptri_has_boundary); /* Find boundary vertices and build a mapping table for compact storage of data. */ - int *vert_boundary_id = static_cast( - MEM_calloc_arrayN(size_t(mesh->totvert), sizeof(int), __func__)); + Array vert_boundary_id(mesh->totvert, 0); for (int i = 0; i < mesh->totedge; i++) { if (edge_mode[i]) { @@ -279,11 +265,9 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) } data->vert_boundary_id = vert_boundary_id; - data->num_boundary_verts = num_boundary_verts; /* Compute average directions. */ - ShrinkwrapBoundaryVertData *boundary_verts = static_cast( - MEM_calloc_arrayN(num_boundary_verts, sizeof(*boundary_verts), __func__)); + Array boundary_verts(num_boundary_verts); signed char *vert_status = static_cast( MEM_calloc_arrayN(num_boundary_verts, sizeof(char), __func__)); @@ -296,8 +280,8 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) sub_v3_v3v3(dir, positions[edge[1]], positions[edge[0]]); normalize_v3(dir); - merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge[0]], dir, 1); - merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge[1]], dir, 2); + merge_vert_dir(boundary_verts.data(), vert_status, vert_boundary_id[edge[0]], dir, 1); + merge_vert_dir(boundary_verts.data(), vert_status, vert_boundary_id[edge[1]], dir, 2); } } @@ -320,7 +304,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) } } - data->boundary_verts = boundary_verts; + data->boundary_verts = std::move(boundary_verts); MEM_freeN(edge_mode); return data; @@ -328,9 +312,6 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh) { - if (mesh->runtime->shrinkwrap_data) { - BKE_shrinkwrap_boundary_data_free(mesh->runtime->shrinkwrap_data); - } mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); } @@ -957,7 +938,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree, #endif /* Retrieve boundary vertex IDs */ - const int *vert_boundary_id = tree->boundary->vert_boundary_id; + const int *vert_boundary_id = tree->boundary->vert_boundary_id.data(); int bid1 = vert_boundary_id[edge[0]], bid2 = vert_boundary_id[edge[1]]; if (bid1 < 0 || bid2 < 0) { @@ -965,7 +946,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree, } /* Retrieve boundary vertex normals and align them to direction. */ - const ShrinkwrapBoundaryVertData *boundary_verts = tree->boundary->boundary_verts; + const ShrinkwrapBoundaryVertData *boundary_verts = tree->boundary->boundary_verts.data(); float vedge_dir[2][3], dir[3]; copy_v3_v3(vedge_dir[0], boundary_verts[bid1].normal_plane); @@ -1060,13 +1041,13 @@ static void mesh_looptri_target_project(void *userdata, update_hit(nearest, index, co, hit_co, hit_no); } /* Boundary edges */ - else if (tree->boundary && BLI_BITMAP_TEST(tree->boundary->looptri_has_boundary, index)) { - const BLI_bitmap *is_boundary = tree->boundary->edge_is_boundary; + else if (tree->boundary && tree->boundary->looptri_has_boundary[index]) { + const BitSpan is_boundary = tree->boundary->edge_is_boundary; const int3 edges = bke::mesh::looptri_get_real_edges( data->edges, data->corner_verts, tree->corner_edges, *lt); for (int i = 0; i < 3; i++) { - if (edges[i] >= 0 && BLI_BITMAP_TEST(is_boundary, edges[i])) { + if (edges[i] >= 0 && is_boundary[edges[i]]) { target_project_edge(tree, index, co, nearest, edges[i]); } } diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index ae89a1fef51..88a9afe4990 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -489,7 +489,7 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->bm = me->edit_mesh->bm; mr->edit_bmesh = me->edit_mesh; mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage; - mr->edit_data = is_mode_active ? mr->me->runtime->edit_data : nullptr; + mr->edit_data = is_mode_active ? mr->me->runtime->edit_data.get() : nullptr; /* If there is no distinct cage, hide unmapped edges that can't be selected. */ mr->hide_unmapped_edges = !do_final || editmesh_eval_final == editmesh_eval_cage; @@ -497,8 +497,8 @@ MeshRenderData *mesh_render_data_create(Object *object, if (mr->edit_data) { blender::bke::EditMeshData *emd = mr->edit_data; if (!emd->vertexCos.is_empty()) { - BKE_editmesh_cache_ensure_vert_normals(mr->edit_bmesh, emd); - BKE_editmesh_cache_ensure_face_normals(mr->edit_bmesh, emd); + BKE_editmesh_cache_ensure_vert_normals(*mr->edit_bmesh, *emd); + BKE_editmesh_cache_ensure_face_normals(*mr->edit_bmesh, *emd); } mr->bm_vert_coords = mr->edit_data->vertexCos; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc index f7a6de789e4..77f92d47d7b 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc @@ -397,7 +397,7 @@ static void statvis_calc_distort(const MeshRenderData &mr, float *r_distort) BMFace *f; if (!mr.bm_vert_coords.is_empty()) { - BKE_editmesh_cache_ensure_face_normals(em, mr.edit_data); + BKE_editmesh_cache_ensure_face_normals(*em, *mr.edit_data); /* Most likely this is already valid, ensure just in case. * Needed for #BM_loop_calc_face_normal_safe_vcos. */