Cleanup: Use C++ Array for dependent shape key data

Avoids manual memory management and potentially avoids
an allocation with the inline buffer.
This commit is contained in:
Hans Goudey
2024-09-16 12:46:54 -04:00
parent 5c792e429f
commit 22cf74d23b
5 changed files with 23 additions and 22 deletions

View File

@@ -6,6 +6,8 @@
#include <optional>
#include <string>
#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<blender::Array<bool>> BKE_keyblock_get_dependent_keys(const Key *key, int index);
/* -------------------------------------------------------------------- */
/** \name Key-Block Data Access

View File

@@ -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<blender::Array<bool>> 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<bool *>(MEM_callocN(sizeof(bool) * count, __func__));
blender::Array<bool> 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. */

View File

@@ -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<Array<bool>> 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);
}
/** \} */

View File

@@ -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<blender::Array<bool>> 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<float *>(
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);
}
/** \} */

View File

@@ -3253,7 +3253,9 @@ void SCULPT_vertcos_to_key(Object &ob, KeyBlock *kb, const Span<float3> 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<blender::Array<bool>> 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<float3> 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<Array<bool>> 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<float3> data(static_cast<float3 *>(other_key->data), other_key->totelem);
apply_translations(translations, verts, data);
}
}
MEM_freeN(dependent);
}
}