From 22cf74d23bf1bda822f518391248220a329b1935 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Sep 2024 12:46:54 -0400 Subject: [PATCH] Cleanup: Use C++ Array for dependent shape key data Avoids manual memory management and potentially avoids an allocation with the inline buffer. --- source/blender/blenkernel/BKE_key.hh | 4 +++- source/blender/blenkernel/intern/key.cc | 12 ++++++------ source/blender/bmesh/intern/bmesh_mesh_convert.cc | 10 ++++------ source/blender/editors/curve/editcurve.cc | 5 ++--- source/blender/editors/sculpt_paint/sculpt.cc | 14 ++++++++------ 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_key.hh b/source/blender/blenkernel/BKE_key.hh index 7c6c4378c28..37929a2e4a7 100644 --- a/source/blender/blenkernel/BKE_key.hh +++ b/source/blender/blenkernel/BKE_key.hh @@ -6,6 +6,8 @@ #include #include +#include "BLI_array.hh" + /** \file * \ingroup bke */ @@ -170,7 +172,7 @@ bool BKE_keyblock_is_basis(const Key *key, int index); * Returns a newly allocated array containing true for every key that has this one as basis. * If none are found, returns null. */ -bool *BKE_keyblock_get_dependent_keys(const Key *key, int index); +std::optional> BKE_keyblock_get_dependent_keys(const Key *key, int index); /* -------------------------------------------------------------------- */ /** \name Key-Block Data Access diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 6605b8bba0c..0b612ff4b09 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2575,20 +2575,21 @@ bool BKE_keyblock_is_basis(const Key *key, const int index) return false; } -bool *BKE_keyblock_get_dependent_keys(const Key *key, const int index) +std::optional> BKE_keyblock_get_dependent_keys(const Key *key, + const int index) { if (key->type != KEY_RELATIVE) { - return nullptr; + return std::nullopt; } const int count = BLI_listbase_count(&key->block); if (index < 0 || index >= count) { - return nullptr; + return std::nullopt; } /* Seed the table with the specified key. */ - bool *marked = static_cast(MEM_callocN(sizeof(bool) * count, __func__)); + blender::Array marked(count, false); marked[index] = true; @@ -2609,8 +2610,7 @@ bool *BKE_keyblock_get_dependent_keys(const Key *key, const int index) } while (updated); if (!found) { - MEM_freeN(marked); - return nullptr; + return std::nullopt; } /* After the search is complete, exclude the original key. */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 91948d81a23..b76903f6c3e 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -792,7 +792,7 @@ static void bm_to_mesh_shape(BMesh *bm, BMIter iter; BMVert *eve; float(*ofs)[3] = nullptr; - bool *dependent = nullptr; + std::optional> dependent; /* Editing the basis key updates others. */ if ((key->type == KEY_RELATIVE) && @@ -801,7 +801,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Original key-indices are only used to check the vertex existed when entering edit-mode. */ (cd_shape_keyindex_offset != -1) && /* Offsets are only needed if the current shape is a basis for others. */ - (dependent = BKE_keyblock_get_dependent_keys(key, bm->shapenr - 1)) != nullptr) + (dependent = BKE_keyblock_get_dependent_keys(key, bm->shapenr - 1)).has_value()) { BLI_assert(actkey != nullptr); /* Assured by `actkey_has_layer` check. */ @@ -828,8 +828,7 @@ static void bm_to_mesh_shape(BMesh *bm, * ones, creating a mess when doing e.g. subdivide + translate. */ MEM_freeN(ofs); ofs = nullptr; - MEM_freeN(dependent); - dependent = nullptr; + dependent.reset(); break; } } @@ -868,7 +867,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Common case, the layer data is available, use it where possible. */ if (cd_shape_offset != -1) { - const bool apply_offset = (ofs != nullptr) && (currkey != actkey) && dependent[currkey_i]; + const bool apply_offset = (ofs != nullptr) && (currkey != actkey) && (*dependent)[currkey_i]; if (currkey->data && (currkey->totelem == bm->totvert)) { /* Use memory in-place. */ @@ -957,7 +956,6 @@ static void bm_to_mesh_shape(BMesh *bm, } MEM_SAFE_FREE(ofs); - MEM_SAFE_FREE(dependent); } /** \} */ diff --git a/source/blender/editors/curve/editcurve.cc b/source/blender/editors/curve/editcurve.cc index 37d43a0aeae..1ace0074324 100644 --- a/source/blender/editors/curve/editcurve.cc +++ b/source/blender/editors/curve/editcurve.cc @@ -657,7 +657,7 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs); float(*ofs)[3] = nullptr; - bool *dependent = nullptr; + std::optional> dependent; float *oldkey, *newkey, *ofp; /* editing the base key should update others */ @@ -723,7 +723,7 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) } LISTBASE_FOREACH_INDEX (KeyBlock *, currkey, &cu->key->block, currkey_i) { - const bool apply_offset = (ofs && (currkey != actkey) && dependent[currkey_i]); + const bool apply_offset = (ofs && (currkey != actkey) && (*dependent)[currkey_i]); float *fp = newkey = static_cast( MEM_callocN(cu->key->elemsize * totvert, "currkey->data")); @@ -887,7 +887,6 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) } MEM_SAFE_FREE(ofs); - MEM_SAFE_FREE(dependent); } /** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index cb4e88ba216..1357e4a37ff 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -3253,7 +3253,9 @@ void SCULPT_vertcos_to_key(Object &ob, KeyBlock *kb, const Span vertCos) const int kb_act_idx = ob.shapenr - 1; /* For relative keys editing of base should update other keys. */ - if (bool *dependent = BKE_keyblock_get_dependent_keys(mesh->key, kb_act_idx)) { + if (std::optional> dependent = BKE_keyblock_get_dependent_keys(mesh->key, + kb_act_idx)) + { ofs = BKE_keyblock_convert_to_vertcos(&ob, kb); /* Calculate key coord offsets (from previous location). */ @@ -3263,13 +3265,12 @@ void SCULPT_vertcos_to_key(Object &ob, KeyBlock *kb, const Span vertCos) /* Apply offsets on other keys. */ LISTBASE_FOREACH_INDEX (KeyBlock *, currkey, &mesh->key->block, currkey_i) { - if ((currkey != kb) && dependent[currkey_i]) { + if ((currkey != kb) && (*dependent)[currkey_i]) { BKE_keyblock_update_from_offset(&ob, currkey, ofs); } } MEM_freeN(ofs); - MEM_freeN(dependent); } /* Modifying of basis key should update mesh. */ @@ -7260,15 +7261,16 @@ void update_shape_keys(Object &object, apply_translations(translations, verts, active_key_data); } - if (bool *dependent = BKE_keyblock_get_dependent_keys(mesh.key, object.shapenr - 1)) { + if (std::optional> dependent = BKE_keyblock_get_dependent_keys(mesh.key, + object.shapenr - 1)) + { int i; LISTBASE_FOREACH_INDEX (KeyBlock *, other_key, &mesh.key->block, i) { - if ((other_key != &active_key) && dependent[i]) { + if ((other_key != &active_key) && (*dependent)[i]) { MutableSpan data(static_cast(other_key->data), other_key->totelem); apply_translations(translations, verts, data); } } - MEM_freeN(dependent); } }