Fix #105720: crash when adding viewer node #105877

Merged
Jacques Lucke merged 3 commits from JacquesLucke/blender:remove-socket-locations-array into blender-v3.5-release 2023-03-19 07:03:13 +01:00
2 changed files with 52 additions and 45 deletions
Showing only changes of commit 17191e910e - Show all commits

View File

@ -370,6 +370,26 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList
return BKE_id_attribute_search(id, uniquename, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
}
static int color_name_to_index(ID *id, const char *name)
{
const CustomDataLayer *layer = BKE_id_attribute_search(
id, name, CD_MASK_COLOR_ALL, ATTR_DOMAIN_MASK_COLOR);
return BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
static int color_clamp_index(ID *id, int index)
{
const int length = BKE_id_attributes_length(id, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
return min_ii(index, length - 1);
}
static const char *color_name_from_index(ID *id, int index)
{
const CustomDataLayer *layer = BKE_id_attribute_from_index(
id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
return layer ? layer->name : nullptr;
}
bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
{
using namespace blender;
@ -403,19 +423,23 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
BM_data_layer_free_named(em->bm, data, BKE_uv_map_pin_name_get(name, buffer_src));
}
}
/* Because it's possible that name is owned by the layer and will be freed
* when freeing the layer, do these checks before freeing. */
/* Update active and default color attributes. */
const bool is_active_color_attribute = name == StringRef(mesh->active_color_attribute);
const bool is_default_color_attribute = name == StringRef(mesh->default_color_attribute);
if (BM_data_layer_free_named(em->bm, data, name)) {
if (is_active_color_attribute) {
MEM_SAFE_FREE(mesh->active_color_attribute);
}
else if (is_default_color_attribute) {
MEM_SAFE_FREE(mesh->default_color_attribute);
}
return true;
const int active_index = color_name_to_index(id, mesh->active_color_attribute);
const int default_index = color_name_to_index(id, mesh->default_color_attribute);
if (!BM_data_layer_free_named(em->bm, data, name)) {
return false;
}
if (is_active_color_attribute) {
BKE_id_attributes_active_color_set(
id, color_name_from_index(id, color_clamp_index(id, active_index)));
}
if (is_default_color_attribute) {
BKE_id_attributes_default_color_set(
id, color_name_from_index(id, color_clamp_index(id, default_index)));
}
return true;
}
}
return false;
@ -429,7 +453,6 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
}
if (GS(id->name) == ID_ME) {
std::optional<blender::bke::AttributeMetaData> metadata = attributes->lookup_meta_data(name);
if (metadata->data_type == CD_PROP_FLOAT2) {
/* remove UV sub-attributes. */
@ -438,6 +461,24 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
BKE_id_attribute_remove(id, BKE_uv_map_edge_select_name_get(name, buffer_src), reports);
BKE_id_attribute_remove(id, BKE_uv_map_pin_name_get(name, buffer_src), reports);
}
/* Update active and default color attributes. */
Mesh *mesh = reinterpret_cast<Mesh *>(id);
const bool is_active_color_attribute = name == StringRef(mesh->active_color_attribute);
const bool is_default_color_attribute = name == StringRef(mesh->default_color_attribute);
const int active_index = color_name_to_index(id, mesh->active_color_attribute);
const int default_index = color_name_to_index(id, mesh->default_color_attribute);
if (!attributes->remove(name)) {
return false;
}
if (is_active_color_attribute) {
BKE_id_attributes_active_color_set(
id, color_name_from_index(id, color_clamp_index(id, active_index)));
}
if (is_default_color_attribute) {
BKE_id_attributes_default_color_set(
id, color_name_from_index(id, color_clamp_index(id, default_index)));
}
return true;
}
return attributes->remove(name);

View File

@ -107,36 +107,6 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static void next_color_attribute(ID *id, const StringRefNull name, bool is_render)
{
const CustomDataLayer *layer = BKE_id_attributes_color_find(id, name.c_str());
int index = BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
index++;
layer = BKE_id_attribute_from_index(id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
if (!layer) {
index = 0;
layer = BKE_id_attribute_from_index(id, index, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
if (layer) {
if (is_render) {
BKE_id_attributes_active_color_set(id, layer->name);
}
else {
BKE_id_attributes_default_color_set(id, layer->name);
}
}
}
static void next_color_attributes(ID *id, const StringRefNull name)
{
next_color_attribute(id, name, false); /* active */
next_color_attribute(id, name, true); /* render */
}
void GEOMETRY_OT_attribute_add(wmOperatorType *ot)
{
/* identifiers */
@ -182,8 +152,6 @@ static int geometry_attribute_remove_exec(bContext *C, wmOperator *op)
ID *id = static_cast<ID *>(ob->data);
CustomDataLayer *layer = BKE_id_attributes_active_get(id);
next_color_attributes(id, layer->name);
if (!BKE_id_attribute_remove(id, layer->name, op->reports)) {
return OPERATOR_CANCELLED;
}
@ -436,8 +404,6 @@ static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
next_color_attributes(id, active_name);
if (!BKE_id_attribute_remove(id, active_name.c_str(), op->reports)) {
return OPERATOR_CANCELLED;
}