Fix #103761: creating a color attribute doesn't make it active #105020

Closed
Philipp Oeser wants to merge 3 commits from lichtwerk:103761 into blender-v3.5-release

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 108 additions and 0 deletions

View File

@ -250,6 +250,88 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
/* ********** */
/**
* When transfering color attributes, also transfer the active color attribute string.
* If a match can't be found, use the first color layer that can be found (to ensure a valid string
* is set).
*/
static void data_transfer_mesh_attributes_transfer_active_color_string(
Mesh *mesh_dst, Mesh *mesh_src, const eAttrDomainMask mask_domain, const int data_type)
Review

const int data_type -> const eCustomDataType data_type

`const int data_type` -> `const eCustomDataType data_type`
{
if (mesh_dst->active_color_attribute) {
Review

BKE_id_attribute_find handles the null name case already

`BKE_id_attribute_find` handles the null name case already
return;
}
const char *active_color_src = BKE_id_attributes_active_color_name(&mesh_src->id);
Review

Use BKE_id_attribute_search(id, name, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER);

Maybe this function can simplify some of the logic below too.

Use `BKE_id_attribute_search(id, name, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER);` Maybe this function can simplify some of the logic below too.
Review

yeah, that simplifies things, thx!

yeah, that simplifies things, thx!
if ((data_type == CD_PROP_COLOR) &&
!BKE_id_attribute_search(&mesh_src->id, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
return;
}
else if ((data_type == CD_PROP_BYTE_COLOR) &&
!BKE_id_attribute_search(&mesh_src->id, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
return;
}
if ((data_type == CD_PROP_COLOR) &&
BKE_id_attribute_search(&mesh_dst->id, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
mesh_dst->active_color_attribute = BLI_strdup(active_color_src);
}
else if ((data_type == CD_PROP_BYTE_COLOR) &&
BKE_id_attribute_search(&mesh_dst->id, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
mesh_dst->active_color_attribute = BLI_strdup(active_color_src);
}
else {
CustomDataLayer *first_color_layer = BKE_id_attribute_from_index(
&mesh_dst->id, 0, mask_domain, CD_MASK_COLOR_ALL);
if (first_color_layer != nullptr) {
Review

cant -> can't

`cant` -> `can't`
mesh_dst->active_color_attribute = BLI_strdup(first_color_layer->name);
}
}
}
/**
* When transfering color attributes, also transfer the default color attribute string.
* If a match cant be found, use the first color layer that can be found (to ensure a valid string
* is set).
*/
static void data_transfer_mesh_attributes_transfer_default_color_string(
Mesh *mesh_dst, Mesh *mesh_src, const eAttrDomainMask mask_domain, const int data_type)
{
if (mesh_dst->default_color_attribute) {
return;
}
const char *default_color_src = BKE_id_attributes_default_color_name(&mesh_src->id);
if ((data_type == CD_PROP_COLOR) &&
!BKE_id_attribute_search(&mesh_src->id, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
return;
}
else if ((data_type == CD_PROP_BYTE_COLOR) &&
!BKE_id_attribute_search(&mesh_src->id, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
return;
}
if ((data_type == CD_PROP_COLOR) &&
BKE_id_attribute_search(&mesh_dst->id, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
mesh_dst->default_color_attribute = BLI_strdup(default_color_src);
}
else if ((data_type == CD_PROP_BYTE_COLOR) &&
BKE_id_attribute_search(&mesh_dst->id, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR)) {
mesh_dst->default_color_attribute = BLI_strdup(default_color_src);
}
else {
CustomDataLayer *first_color_layer = BKE_id_attribute_from_index(
&mesh_dst->id, 0, mask_domain, CD_MASK_COLOR_ALL);
if (first_color_layer != nullptr) {
mesh_dst->default_color_attribute = BLI_strdup(first_color_layer->name);
}
}
}
/* ********** */
/* Generic pre/post processing, only used by custom loop normals currently. */
static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
@ -1124,6 +1206,14 @@ void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph,
fromlayers,
tolayers,
nullptr);
/* Make sure we have active/defaut color layers if none existed before.
* Use the active/defaut from src (if it was transferred), otherwise the first. */
if (ELEM(cddata_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
data_transfer_mesh_attributes_transfer_active_color_string(
me_dst, me_src, ATTR_DOMAIN_MASK_POINT, cddata_type);
data_transfer_mesh_attributes_transfer_default_color_string(
me_dst, me_src, ATTR_DOMAIN_MASK_POINT, cddata_type);
}
}
if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
const int num_elem_dst = me_dst->totedge;
@ -1164,6 +1254,14 @@ void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph,
fromlayers,
tolayers,
nullptr);
/* Make sure we have active/defaut color layers if none existed before.
* Use the active/defaut from src (if it was transferred), otherwise the first. */
if (ELEM(cddata_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
data_transfer_mesh_attributes_transfer_active_color_string(
me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
data_transfer_mesh_attributes_transfer_default_color_string(
me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
}
}
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
const int num_elem_dst = me_dst->totpoly;

View File

@ -491,6 +491,8 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
}
BKE_id_attributes_active_color_set(
&me->id, CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, 0));
BKE_id_attributes_default_color_set(
&me->id, CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, 0));
}
}
}

View File

@ -401,6 +401,7 @@ void MeshFromGeometry::create_colors(Mesh *mesh)
CustomDataLayer *color_layer = BKE_id_attribute_new(
&mesh->id, "Color", CD_PROP_COLOR, ATTR_DOMAIN_POINT, nullptr);
BKE_id_attributes_active_color_set(&mesh->id, color_layer->name);
BKE_id_attributes_default_color_set(&mesh->id, color_layer->name);
float4 *colors = (float4 *)color_layer->data;
int offset = mesh_geometry_.vertex_index_min_ - block.start_vertex_index;
for (int i = 0, n = mesh_geometry_.get_vertex_count(); i != n; ++i) {

View File

@ -2292,6 +2292,13 @@ static PointerRNA rna_Mesh_vertex_color_new(struct Mesh *me,
if (index != -1) {
ldata = rna_mesh_ldata_helper(me);
cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_BYTE_COLOR, index)];
if (!me->active_color_attribute) {
me->active_color_attribute = BLI_strdup(cdl->name);
}
if (!me->default_color_attribute) {
me->default_color_attribute = BLI_strdup(cdl->name);
}
}
RNA_pointer_create(&me->id, &RNA_MeshLoopColorLayer, cdl, &ptr);