Sculpt-dev: Add support for attribute triplets

It simply wasn't maintainable to store active/render
vertex color layer as integer indices into the
global attribute list.  Making that work would've
required a great deal of boilerplate that would
have to be inserted in lots of places.  There
is simply no justification for doing that.

Instead, I've coded an AttributeRef struct that
simply stores a (type, name, domain) triplet to
uniquely reference an attribute layer.

This will be submitted as a patch for master
too.
This commit is contained in:
Joseph Eagar 2021-11-16 21:58:50 -08:00
parent b2c64e2147
commit 7a55066b18
15 changed files with 277 additions and 341 deletions

View File

@ -451,9 +451,13 @@ class MESH_UL_color_attributes(UIList):
bad = item.domain not in ["POINT", "CORNER"]
bad = bad or item.data_type not in ["FLOAT_COLOR", "BYTE_COLOR"]
#if not bad:
#print(bad, idx, item.name, item.domain, item.data_type)
ret.append(self.bitflag_filter_item if not bad else 0)
idxs.append(idx)
# note this is index in full attribute list, not color list
idx += 1
return ret, idxs

View File

@ -36,6 +36,7 @@ struct CustomData;
struct CustomDataLayer;
struct ID;
struct ReportList;
struct AttributeRef;
/* Attribute.domain */
/**
@ -53,6 +54,15 @@ typedef enum AttributeDomain {
ATTR_DOMAIN_NUM
} AttributeDomain;
typedef enum {
ATTR_DOMAIN_MASK_POINT = (1 << 0),
ATTR_DOMAIN_MASK_EDGE = (1 << 1),
ATTR_DOMAIN_MASK_FACE = (1 << 2),
ATTR_DOMAIN_MASK_CORNER = (1 << 3),
ATTR_DOMAIN_MASK_CURVE = (1 << 4),
ATTR_DOMAIN_MASK_ALL = (1 << 5) - 1
} AttributeDomainMask;
/* Attributes */
bool BKE_id_attributes_supported(struct ID *id);
@ -60,6 +70,7 @@ bool BKE_id_attributes_supported(struct ID *id);
struct CustomDataLayer *BKE_id_attribute_new(struct ID *id,
const char *name,
const int type,
CustomDataMask list_mask,
const AttributeDomain domain,
struct ReportList *reports);
bool BKE_id_attribute_remove(struct ID *id,
@ -79,7 +90,9 @@ bool BKE_id_attribute_rename(struct ID *id,
const char *new_name,
struct ReportList *reports);
int BKE_id_attributes_length(struct ID *id, const CustomDataMask mask);
int BKE_id_attributes_length(const struct ID *id,
const AttributeDomainMask domain_mask,
const CustomDataMask mask);
struct CustomDataLayer *BKE_id_attributes_active_get(struct ID *id);
void BKE_id_attributes_active_set(struct ID *id, struct CustomDataLayer *layer);
@ -88,11 +101,11 @@ int *BKE_id_attributes_active_index_p(struct ID *id);
CustomData *BKE_id_attributes_iterator_next_domain(struct ID *id, struct CustomDataLayer *layers);
CustomDataLayer *BKE_id_attribute_from_index(const struct ID *id, int lookup_index);
int *BKE_id_attributes_active_color_index_p(struct ID *id);
struct AttributeRef *BKE_id_attributes_active_color_ref_p(struct ID *id);
void BKE_id_attributes_active_color_set(struct ID *id, struct CustomDataLayer *active_layer);
struct CustomDataLayer *BKE_id_attributes_active_color_get(struct ID *id);
int *BKE_id_attributes_render_color_index_p(struct ID *id);
struct AttributeRef *BKE_id_attributes_render_color_ref_p(struct ID *id);
void BKE_id_attributes_render_color_set(struct ID *id, struct CustomDataLayer *active_layer);
CustomDataLayer *BKE_id_attributes_render_color_get(struct ID *id);
@ -100,6 +113,18 @@ bool BKE_id_attribute_find_unique_name(struct ID *id,
const char *name,
char *outname,
CustomDataMask mask);
int BKE_id_attribute_index_from_ref(struct ID *id,
struct AttributeRef *ref,
AttributeDomainMask domain_mask,
CustomDataMask type_filter);
bool BKE_id_attribute_ref_from_index(struct ID *id,
int attr_index,
AttributeDomainMask domain_mask,
CustomDataMask type_filter,
struct AttributeRef *r_ref);
#ifdef __cplusplus
}
#endif

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 2
#define BLENDER_FILE_SUBVERSION 3
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file

View File

@ -189,13 +189,17 @@ bool BKE_id_attribute_find_unique_name(ID *id,
{
AttrUniqueData data = {.id = id, .mask = mask};
BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
BLI_strncpy_utf8(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
return BLI_uniquename_cb(unique_name_cb, &data, NULL, '.', outname, MAX_CUSTOMDATA_LAYER_NAME);
}
CustomDataLayer *BKE_id_attribute_new(
ID *id, const char *name, const int type, const AttributeDomain domain, ReportList *reports)
CustomDataLayer *BKE_id_attribute_new(ID *id,
const char *name,
const int type,
CustomDataMask list_mask,
const AttributeDomain domain,
ReportList *reports)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
@ -206,12 +210,9 @@ CustomDataLayer *BKE_id_attribute_new(
return NULL;
}
char uniquename[sizeof(customdata->layers->name)];
BKE_id_attribute_find_unique_name(
id,
name,
uniquename,
((1ULL << type) & CD_MASK_PROP_ALL) ? CD_MASK_PROP_ALL : (CustomDataMask)(1ULL << type));
char uniquename[MAX_CUSTOMDATA_LAYER_NAME];
BKE_id_attribute_find_unique_name(id, name, uniquename, list_mask);
switch (GS(id->name)) {
case ID_ME: {
@ -327,7 +328,9 @@ CustomDataLayer *BKE_id_attribute_from_index(const ID *id, int lookup_index)
return NULL;
}
int BKE_id_attributes_length(ID *id, const CustomDataMask mask)
int BKE_id_attributes_length(const ID *id,
const AttributeDomainMask domain_mask,
const CustomDataMask mask)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
@ -336,7 +339,8 @@ int BKE_id_attributes_length(ID *id, const CustomDataMask mask)
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (customdata) {
if (customdata && ((1 << (int)domain) & domain_mask)) {
length += CustomData_number_of_layers_typemask(customdata, mask);
}
}
@ -393,7 +397,7 @@ bool BKE_id_attribute_required(ID *id, CustomDataLayer *layer)
CustomDataLayer *BKE_id_attributes_active_get(ID *id)
{
int active_index = *BKE_id_attributes_active_index_p(id);
if (active_index > BKE_id_attributes_length(id, CD_MASK_PROP_ALL)) {
if (active_index > BKE_id_attributes_length(id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL)) {
active_index = 0;
}
@ -463,46 +467,30 @@ int *BKE_id_attributes_active_index_p(ID *id)
CustomDataLayer *BKE_id_attributes_active_color_get(ID *id)
{
int active_index = *BKE_id_attributes_active_color_index_p(id);
if (active_index > BKE_id_attributes_length(id, CD_MASK_PROP_ALL)) {
fprintf(stderr, "bad active color index %d; was out of bounds\n", active_index);
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(id);
if (!ref) {
fprintf(stderr, "%s: vertex colors not supported for this type\n", __func__);
return NULL;
}
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
int index = 0;
int idx = CustomData_get_named_layer_index(info[ref->domain].customdata, ref->type, ref->name);
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (customdata) {
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(layer->type)) {
if (index == active_index) {
if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER) &&
ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
return layer;
}
else {
fprintf(
stderr, "bad active color index %d; type was: %d\n", active_index, layer->type);
return NULL;
}
}
index++;
}
}
}
}
return NULL;
return idx != -1 ? info[ref->domain].customdata->layers + idx : NULL;
}
void BKE_id_attributes_active_color_set(ID *id, CustomDataLayer *active_layer)
{
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(id);
if (!ref) {
fprintf(stderr, "%s: vertex colors not supported for this type\n", __func__);
return;
}
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
@ -514,31 +502,29 @@ void BKE_id_attributes_active_color_set(ID *id, CustomDataLayer *active_layer)
return;
}
int index = 0;
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (customdata) {
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if (layer == active_layer && ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
*BKE_id_attributes_active_color_index_p(id) = index;
ref->type = layer->type;
ref->domain = domain;
BLI_strncpy_utf8(ref->name, layer->name, MAX_CUSTOMDATA_LAYER_NAME);
return;
}
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(layer->type)) {
index++;
}
}
}
}
}
int *BKE_id_attributes_active_color_index_p(ID *id)
AttributeRef *BKE_id_attributes_active_color_ref_p(ID *id)
{
switch (GS(id->name)) {
case ID_ME: {
return &((Mesh *)id)->active_color_index;
return &((Mesh *)id)->attr_color_active;
}
default:
return NULL;
@ -547,46 +533,30 @@ int *BKE_id_attributes_active_color_index_p(ID *id)
CustomDataLayer *BKE_id_attributes_render_color_get(ID *id)
{
int active_index = *BKE_id_attributes_render_color_index_p(id);
if (active_index > BKE_id_attributes_length(id, CD_MASK_PROP_ALL)) {
fprintf(stderr, "bad active color index %d; was out of bounds\n", active_index);
AttributeRef *ref = BKE_id_attributes_render_color_ref_p(id);
if (!ref) {
fprintf(stderr, "%s: vertex colors not supported for this type\n", __func__);
return NULL;
}
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
int index = 0;
int idx = CustomData_get_named_layer_index(info[ref->domain].customdata, ref->type, ref->name);
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (customdata) {
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(layer->type)) {
if (index == active_index) {
if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER) &&
ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
return layer;
}
else {
fprintf(
stderr, "bad active color index %d; type was: %d\n", active_index, layer->type);
return NULL;
}
}
index++;
}
}
}
}
return NULL;
return idx != -1 ? info[ref->domain].customdata->layers + idx : NULL;
}
void BKE_id_attributes_render_color_set(ID *id, CustomDataLayer *active_layer)
{
AttributeRef *ref = BKE_id_attributes_render_color_ref_p(id);
if (!ref) {
fprintf(stderr, "%s: vertex colors not supported for this type\n", __func__);
return;
}
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
@ -598,31 +568,101 @@ void BKE_id_attributes_render_color_set(ID *id, CustomDataLayer *active_layer)
return;
}
int index = 0;
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (customdata) {
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if (layer == active_layer && ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
*BKE_id_attributes_render_color_index_p(id) = index;
ref->type = layer->type;
ref->domain = domain;
BLI_strncpy_utf8(ref->name, layer->name, MAX_CUSTOMDATA_LAYER_NAME);
return;
}
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(layer->type)) {
index++;
}
}
}
}
}
int *BKE_id_attributes_render_color_index_p(ID *id)
int BKE_id_attribute_index_from_ref(ID *id,
AttributeRef *ref,
AttributeDomainMask domain_mask,
CustomDataMask type_filter)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
int index = 0;
for (AttributeDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *data = info[domain].customdata;
if (!((1 << (int)domain) & domain_mask) || !data) {
continue;
}
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = data->layers + i;
if (layer->type == ref->type &&
STREQ(layer->name, ref->name)) {
return index;
}
if (CD_TYPE_AS_MASK(layer->type) & type_filter) {
index++;
}
}
}
return -1;
}
bool BKE_id_attribute_ref_from_index(ID *id,
int attr_index,
AttributeDomainMask domain_mask,
CustomDataMask type_filter,
AttributeRef *r_ref)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
int index = 0;
for (AttributeDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *data = info[domain].customdata;
if (!data || !((1 << (int)domain) & domain_mask)) {
continue;
}
for (int i = 0; i < data->totlayer; i++) {
CustomDataLayer *layer = data->layers + i;
if (index == attr_index) {
r_ref->domain = domain;
r_ref->type = layer->type;
BLI_strncpy_utf8(r_ref->name, layer->name, MAX_CUSTOMDATA_LAYER_NAME);
return true;
}
if (CD_TYPE_AS_MASK(layer->type) & type_filter) {
index++;
}
}
}
return false;
}
AttributeRef *BKE_id_attributes_render_color_ref_p(ID *id)
{
switch (GS(id->name)) {
case ID_ME: {
return &((Mesh *)id)->render_color_index;
return &((Mesh *)id)->attr_color_render;
}
default:
return NULL;

View File

@ -3345,7 +3345,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
if (use_speedvectors) {
CustomDataLayer *velocity_layer = BKE_id_attribute_new(
&me->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, NULL);
&me->id, "velocity", CD_PROP_FLOAT3, CD_MASK_PROP_ALL, ATTR_DOMAIN_POINT, NULL);
velarray = velocity_layer->data;
}

View File

@ -2273,196 +2273,3 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
}
}
}
void BKE_mesh_attributes_update_pre(Mesh *me,
AttributeDomain domain,
CustomDataMergeState *state)
{
CustomDataLayer *active = BKE_id_attributes_active_get((ID *)me);
CustomDataLayer *active_color = BKE_id_attributes_active_color_get((ID *)me);
CustomDataLayer *render_color = BKE_id_attributes_render_color_get((ID *)me);
CustomData *dst = NULL;
switch (domain) {
case ATTR_DOMAIN_POINT:
dst = &me->vdata;
break;
case ATTR_DOMAIN_EDGE:
dst = &me->edata;
break;
case ATTR_DOMAIN_CORNER:
dst = &me->ldata;
break;
case ATTR_DOMAIN_FACE:
dst = &me->pdata;
break;
default:
// should never happen
fprintf(stderr, "%s: bad domain!\n", __func__);
return;
}
state->dst = dst;
/* check that domain is correct */
active = active && BKE_id_attribute_domain((ID *)me, active) != domain ? NULL : active;
active_color = active_color && BKE_id_attribute_domain((ID *)me, active_color) != domain ?
NULL :
active_color;
render_color = render_color && BKE_id_attribute_domain((ID*)me, render_color) != domain ? NULL : render_color;
if (active) {
state->active_type = active->type;
BLI_strncpy(state->active_name, active->name, sizeof(state->active_name));
}
else {
state->active_type = -1;
}
if (active_color) {
state->active_color_type = active_color->type;
BLI_strncpy(state->active_color_name, active_color->name, sizeof(state->active_color_name));
}
else {
state->active_color_type = -1;
}
if (render_color) {
state->render_color_type = render_color->type;
BLI_strncpy(state->render_color_name, render_color->name, sizeof(state->render_color_name));
}
else {
state->render_color_type = -1;
}
}
void BKE_mesh_attributes_update_post(Mesh *me,
AttributeDomain domain,
CustomDataMergeState *state)
{
int active_idx = state->active_type != -1 ?
CustomData_get_named_layer_index(state->dst, state->active_type, state->active_name) :
-1;
int active_color_idx = state->active_color_type != -1 ?
CustomData_get_named_layer_index(
state->dst, state->active_color_type, state->active_color_name) :
-1;
int render_color_idx = state->render_color_type != -1 ?
CustomData_get_named_layer_index(
state->dst, state->render_color_type, state->render_color_name) :
-1;
if (active_idx != -1) {
BKE_id_attributes_active_set((ID *)me, state->dst->layers + active_idx);
}
if (active_color_idx != -1) {
BKE_id_attributes_active_color_set((ID *)me, state->dst->layers + active_color_idx);
}
else if (state->active_color_type != -1) {
bool ok = false;
// layer disappeared, find a new one
for (int i = 0; i < state->dst->totlayer; i++) {
if (ELEM(state->dst->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL)) {
ok = true;
BKE_id_attributes_active_color_set((ID *)me, state->dst->layers + i);
break;
}
}
if (!ok) {
// failed to find one? try other color attribute domain
CustomData *other = domain == ATTR_DOMAIN_POINT ? &me->ldata : &me->vdata;
for (int i = 0; i < other->totlayer; i++) {
if (ELEM(other->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_active_color_set((ID *)me, other->layers + i);
break;
}
}
}
}
if (render_color_idx != -1) {
BKE_id_attributes_render_color_set((ID *)me, state->dst->layers + render_color_idx);
}
else if (state->render_color_type != -1) {
bool ok = false;
// layer disappeared, find a new one
for (int i = 0; i < state->dst->totlayer; i++) {
if (ELEM(state->dst->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL)) {
ok = true;
BKE_id_attributes_render_color_set((ID *)me, state->dst->layers + i);
break;
}
}
if (!ok) {
// failed to find one? try other color attribute domain
CustomData *other = domain == ATTR_DOMAIN_POINT ? &me->ldata : &me->vdata;
for (int i = 0; i < other->totlayer; i++) {
if (ELEM(other->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_render_color_set((ID *)me, other->layers + i);
break;
}
}
}
}
}
bool BKE_mesh_customdata_merge(Mesh *me,
AttributeDomain domain,
CustomData *src,
CustomDataMask mask,
eCDAllocType alloctype,
int totelem)
{
int active_type, active_color_type;
char active_name[MAX_CUSTOMDATA_LAYER_NAME];
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME];
CustomDataMergeState state;
BKE_mesh_attributes_update_pre(
me, domain, &state);
if (!state.dst) {
return false;
}
bool ret = CustomData_merge(src, state.dst, mask, alloctype, totelem);
BKE_mesh_attributes_update_post(
me, domain, &state);
return ret;
}
void BKE_mesh_customdata_copy(Mesh *me,
AttributeDomain domain,
CustomData *src,
CustomDataMask mask,
eCDAllocType alloctype,
int totelem)
{
int active_type, active_color_type;
char active_name[MAX_CUSTOMDATA_LAYER_NAME];
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME];
CustomDataMergeState state;
BKE_mesh_attributes_update_pre(
me, domain, &state);
if (!state.dst) {
return;
}
CustomData_copy(src, state.dst, mask, alloctype, totelem);
BKE_mesh_attributes_update_post(
me, domain, &state);
}

View File

@ -41,6 +41,7 @@
#include "DNA_lineart_types.h"
#include "DNA_listBase.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_text_types.h"
#include "DNA_workspace_types.h"
@ -49,6 +50,7 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_asset.h"
#include "BKE_attribute.h"
#include "BKE_brush.h"
#include "BKE_brush_engine.h"
#include "BKE_collection.h"
@ -2521,6 +2523,58 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 301, 3)) {
LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) {
AttributeRef ref;
for (int step = 0; step < 2; step++) {
bool bad = false;
CustomDataLayer *actlayer = NULL;
int actidx = step ? me->render_color_index : me->active_color_index;
if (BKE_id_attribute_ref_from_index(
&me->id, actidx, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL, &ref)) {
if (!ELEM(ref.type, CD_PROP_COLOR, CD_MLOOPCOL) ||
!ELEM(ref.domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
bad = true;
}
else {
actlayer = BKE_id_attribute_find(&me->id, ref.name, ref.type, ref.domain);
}
}
if (bad) {
int vact1, vact2;
if (step) {
vact1 = CustomData_get_render_layer_index(&me->vdata, CD_PROP_COLOR);
vact2 = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL);
}
else {
vact1 = CustomData_get_active_layer_index(&me->vdata, CD_PROP_COLOR);
vact2 = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL);
}
if (vact1 != -1) {
actlayer = me->vdata.layers + vact1;
}
else if (vact2 != -1) {
actlayer = me->ldata.layers + vact2;
}
}
if (actlayer) {
if (step) {
BKE_id_attributes_render_color_set(&me->id, actlayer);
}
else {
BKE_id_attributes_active_color_set(&me->id, actlayer);
}
}
}
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -1068,16 +1068,8 @@ void BM_mesh_bm_to_me(
#endif
}
int active_domains[4] = {
ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_CORNER, ATTR_DOMAIN_FACE};
CustomDataMergeState attr_states[4];
// undo mesh?
bool non_id_mesh = GS(me->id.name) != ID_ME;
for (int i = 0; !non_id_mesh && i < 4; i++) {
BKE_mesh_attributes_update_pre(me, active_domains[i], attr_states + i);
}
//undo mesh?
//bool non_id_mesh = GS(me->id.name) != ID_ME;
/* Free custom data. */
CustomData_free(&me->vdata, me->totvert);
@ -1136,11 +1128,6 @@ void BM_mesh_bm_to_me(
/* This is called again, 'dotess' arg is used there. */
BKE_mesh_update_customdata_pointers(me, 0);
for (int i = 0; !non_id_mesh && i < 4; i++) {
CustomData *dst;
BKE_mesh_attributes_update_post(me, active_domains[i], attr_states + i);
}
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
copy_v3_v3(mvert->co, v->co);
@ -1548,11 +1535,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *
}
mask.vmask &= ~CD_MASK_SHAPEKEY;
BKE_mesh_customdata_merge(me, ATTR_DOMAIN_POINT, &bm->vdata, mask.vmask, CD_CALLOC, me->totvert);
BKE_mesh_customdata_merge(me, ATTR_DOMAIN_EDGE, &bm->edata, mask.emask, CD_CALLOC, me->totedge);
BKE_mesh_customdata_merge(
me, ATTR_DOMAIN_CORNER, &bm->ldata, mask.lmask, CD_CALLOC, me->totloop);
BKE_mesh_customdata_merge(me, ATTR_DOMAIN_FACE, &bm->pdata, mask.pmask, CD_CALLOC, me->totpoly);
CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
BKE_mesh_update_customdata_pointers(me, false);

View File

@ -51,7 +51,7 @@ static void extract_vcol_init(const MeshRenderData *mr,
*/
int vcol_types[2] = {CD_MLOOPCOL, CD_PROP_COLOR};
CustomDataLayer *actlayer = BKE_id_attributes_active_get((ID *)mr->me);
CustomDataLayer *actlayer = BKE_id_attributes_active_color_get((ID *)mr->me);
AttributeDomain actdomain = actlayer ? BKE_id_attribute_domain((ID *)mr->me, actlayer) :
ATTR_DOMAIN_AUTO;
int actn = -1;

View File

@ -88,9 +88,11 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
RNA_string_get(op->ptr, "name", name);
CustomDataType type = (CustomDataType)RNA_enum_get(op->ptr, "data_type");
AttributeDomain domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain");
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports);
CustomDataLayer *layer = BKE_id_attribute_new(
id, name, type, CD_MASK_PROP_ALL, domain, op->reports);
if (layer == NULL) {
return OPERATOR_CANCELLED;

View File

@ -464,7 +464,7 @@ static void read_velocity(const V3fArraySamplePtr &velocities,
const float velocity_scale)
{
CustomDataLayer *velocity_layer = BKE_id_attribute_new(
&config.mesh->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, nullptr);
&config.mesh->id, "velocity", CD_PROP_FLOAT3, CD_MASK_PROP_ALL, ATTR_DOMAIN_POINT, nullptr);
float(*velocity)[3] = (float(*)[3])velocity_layer->data;
const int num_velocity_vectors = static_cast<int>(velocities->size());

View File

@ -133,6 +133,11 @@ typedef struct Mesh_Runtime {
} Mesh_Runtime;
typedef struct AttributeRef {
int domain, type;
char name[64];
} AttributeRef;
typedef struct Mesh {
ID id;
/** Animation data (must be immediately after id for utilities to use it). */
@ -197,11 +202,14 @@ typedef struct Mesh {
int attributes_active_index;
int vertex_group_active_index;
int active_color_index DNA_DEPRECATED;
int render_color_index DNA_DEPRECATED;
/* note that this can be inside of either vdata or ldata,
and can reference a layer of type CD_PROP_COLOR or
CD_MLOOPCOL */
int active_color_index;
int render_color_index;
AttributeRef attr_color_active;
AttributeRef attr_color_render;
/* the last selected vertex/edge/face are used for the active face however
* this means the active face must always be selected, this is to keep track

View File

@ -181,13 +181,18 @@ static bool rna_Attribute_active_render_get(PointerRNA *ptr)
case ATTR_DOMAIN_FACE:
cdata = &me->pdata;
break;
default:
return false;
}
if (!cdata) {
int idx = CustomData_get_layer_index(cdata, layer->type);
if (idx == -1) {
return false;
}
CustomDataLayer *base = CustomData_get_layer_index(cdata, layer->type);
CustomDataLayer *base = cdata->layers + idx;
return layer == base + base->active_rnd;
}
@ -211,7 +216,7 @@ static void rna_Attribute_active_render_set(PointerRNA *ptr, bool value)
Mesh *me = (Mesh *)id;
AttributeDomain domain = BKE_id_attribute_domain(id, layer);
CustomData *cdata = NULL;
CustomData *cdata;
switch (domain) {
case ATTR_DOMAIN_POINT:
@ -226,22 +231,22 @@ static void rna_Attribute_active_render_set(PointerRNA *ptr, bool value)
case ATTR_DOMAIN_FACE:
cdata = &me->pdata;
break;
}
if (!cdata) {
return;
default:
return;
}
if (ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_render_color_set(id, layer);
}
else {
int idx = CustomData_get_layer_index(cdata, layer->type);
CustomDataLayer *base = CustomData_get_layer_index(cdata, layer->type);
int idx = base - cdata->layers;
int newrender = layer - base;
if (idx != -1) {
CustomDataLayer *base = cdata->layers + idx;
int newrender = layer - base;
CustomData_set_layer_render(cdata, layer->type, newrender);
CustomData_set_layer_render(cdata, layer->type, newrender);
}
}
}
@ -390,7 +395,7 @@ static void rna_ByteColorAttributeValue_color_set(PointerRNA *ptr, const float *
static PointerRNA rna_AttributeGroup_new(
ID *id, ReportList *reports, const char *name, const int type, const int domain)
{
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, reports);
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, CD_MASK_PROP_ALL, domain, reports);
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
@ -464,12 +469,14 @@ PointerRNA rna_AttributeGroup_iterator_get(CollectionPropertyIterator *iter)
int rna_AttributeGroup_length(PointerRNA *ptr)
{
return BKE_id_attributes_length(ptr->owner_id, CD_MASK_PROP_ALL);
return BKE_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
}
static int rna_AttributeGroup_active_index_get(PointerRNA *ptr)
{
return *BKE_id_attributes_active_index_p(ptr->owner_id);
int *active = BKE_id_attributes_active_index_p(ptr->owner_id);
return active ? *active : 0;
}
static PointerRNA rna_AttributeGroup_active_get(PointerRNA *ptr)
@ -500,7 +507,7 @@ static void rna_AttributeGroup_active_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
*min = 0;
*max = BKE_id_attributes_length(ptr->owner_id, CD_MASK_PROP_ALL);
*max = BKE_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
*softmin = *min;
*softmax = *max;
@ -533,25 +540,26 @@ static void rna_AttributeGroup_active_color_set(PointerRNA *ptr,
static int rna_AttributeGroup_active_color_index_get(PointerRNA *ptr)
{
int *active = BKE_id_attributes_active_color_index_p(ptr->owner_id);
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(ptr->owner_id);
return active ? *active : -1;
return ref ? BKE_id_attribute_index_from_ref(ptr->owner_id,
ref,
ATTR_DOMAIN_MASK_ALL,
CD_MASK_PROP_ALL) :
0;
}
static void rna_AttributeGroup_active_color_index_set(PointerRNA *ptr, int value)
{
ID *id = ptr->owner_id;
int *active = BKE_id_attributes_active_color_index_p(ptr->owner_id);
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(ptr->owner_id);
if (active) {
CustomDataLayer *layer = BKE_id_attribute_from_index(id, value);
if (layer) {
BKE_id_attributes_active_color_set(id, layer);
}
else {
fprintf(stderr, "%s: error setting active color index to %d\n", __func__, value);
}
if (!ref || !BKE_id_attribute_ref_from_index(id,
value,
ATTR_DOMAIN_MASK_ALL,
CD_MASK_PROP_ALL,
ref)) {
fprintf(stderr, "%s: error setting active color index to %d\n", __func__, value);
}
}
@ -559,7 +567,8 @@ static void rna_AttributeGroup_active_color_index_range(
PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
{
*min = 0;
*max = BKE_id_attributes_length(ptr->owner_id, CD_MASK_PROP_ALL);
*max = BKE_id_attributes_length(
ptr->owner_id, ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER, CD_MASK_PROP_COLOR|CD_MASK_MLOOPCOL);
*softmin = *min;
*softmax = *max;

View File

@ -724,7 +724,7 @@ static void rna_Brush_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR
static void rna_Brush_dyntopo_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
//Brush *br = (Brush *)ptr->data;
}
static void rna_Brush_material_update(bContext *UNUSED(C), PointerRNA *UNUSED(ptr))

View File

@ -211,7 +211,7 @@ struct StructRNA *rna_BrushChannel_refine(PointerRNA *ptr)
BrushChannelSet *rna_BrushChannelSet_get_set(struct PointerRNA *ptr)
{
BrushChannelSet *chset = NULL;
BrushChannelSet *chset;
ID *id = ptr->owner_id;
switch (GS(id->name)) {
@ -228,6 +228,8 @@ BrushChannelSet *rna_BrushChannelSet_get_set(struct PointerRNA *ptr)
chset = scene->toolsettings->sculpt->channels;
break;
}
default:
return NULL;
}
return chset;
@ -577,7 +579,6 @@ static void rna_BrushChannel_enum_items_begin(CollectionPropertyIterator *iter,
char *rna_BrushChannel_rnapath(PointerRNA *ptr)
{
BrushChannel *ch = (BrushChannel *)ptr->data;
char buf[512];
if (!ptr->owner_id) {
return NULL;
@ -626,7 +627,7 @@ int rna_BrushChannel_category_length(PointerRNA *ptr)
return strlen(BKE_brush_channel_category_get((BrushChannel *)ptr->data));
}
int rna_BrushChannel_factor_value_editable(PointerRNA *ptr)
int rna_BrushChannel_factor_value_editable(PointerRNA *ptr, const char **r_info)
{
return 1;
}