Fix #105152: Removing color attribute doesn't update active #105871
|
@ -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);
|
||||
bonj marked this conversation as resolved
Outdated
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
I'd suggest flipping the condition here and returning early instead of indenting the rest of the logic.