Fix T102404: Behavior change in CustomData API

Previously the `CustomData_add_layer` function always returned
the existing layer data when used for types that can only have one
layer. This made it work like an "ensure layer exists" function for those
types. That was used in various places to make code more concise.

0a7308a0f1 changed that to always "recreate" the layer even
when it existed. Maybe this is more logical for an "add layer" function,
but that's not clear, and it breaks a bunch of existing code that relied
on the current behavior. Rather than spending a bunch of time going
through uses of the CustomData API, this patch resets the behavior
to what it was before, but adds an assert and a comment to help
avoid memory leaks and other issues. We should focus on moving
to the attribute API instead.

Differential Revision: https://developer.blender.org/D16458
This commit is contained in:
Hans Goudey 2022-11-11 09:07:54 -06:00
parent e508de0417
commit ff7645c5ed
Notes: blender-bot 2023-10-07 14:34:11 +02:00
Referenced by issue #102419, Regression: Geometry nodes Missing Mesh overlays in edit mode
Referenced by issue #102419, Regression: Geometry nodes Missing Mesh overlays in edit mode
Referenced by issue #102404, Reading+Writing edge bevel weights with python api only working correctly on last element
Referenced by issue #113377, Regression: Geometry Nodes: Access Violation Exception when copying from Mesh with GPU Subdivision Surface Modifier
1 changed files with 8 additions and 15 deletions

View File

@ -2799,6 +2799,14 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
int flag = 0;
/* Some layer types only support a single layer. */
if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
/* This function doesn't support dealing with existing layer data for these layer types when
* the layer already exists. */
BLI_assert(layerdata == nullptr);
return &data->layers[CustomData_get_layer_index(data, type)];
}
void *newlayerdata = nullptr;
switch (alloctype) {
case CD_SET_DEFAULT:
@ -2851,21 +2859,6 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
break;
}
/* Some layer types only support a single layer. */
const bool reuse_existing_layer = !typeInfo->defaultname && CustomData_has_layer(data, type);
if (reuse_existing_layer) {
CustomDataLayer &layer = data->layers[CustomData_get_layer_index(data, type)];
if (layer.data != nullptr) {
if (typeInfo->free) {
typeInfo->free(layer.data, totelem, typeInfo->size);
}
MEM_SAFE_FREE(layer.data);
}
layer.data = newlayerdata;
layer.flag = flag;
return &layer;
}
int index = data->totlayer;
if (index >= data->maxlayer) {
if (!customData_resize(data, CUSTOMDATA_GROW)) {