Sculpt-dev: get vcol render layer working

* Mesh now has a render_color_index member.
  + We really need an attribute ref system
    based on (domain, type, name) triplets.
* RNA uses render_color_index in all three
  cases (loop colors, vert colors, and
         the generic attribute types).
* PBVH draw uses render_color_index too.
This commit is contained in:
Joseph Eagar 2021-11-09 00:11:03 -08:00
parent f0d0369506
commit 0569618578
18 changed files with 450 additions and 113 deletions

View File

@ -466,6 +466,9 @@ class MESH_UL_color_attributes(UIList):
split = layout.split(factor=0.50)
split.emboss = 'NONE'
split.prop(attribute, "name", text="")
split.prop(attribute, "active_render", text="", icon = 'RESTRICT_RENDER_OFF' if attribute.active_render else 'RESTRICT_RENDER_ON')
sub = split.row()
sub.alignment = 'RIGHT'
sub.active = False
@ -526,8 +529,6 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
add_builtin("crease")
add_attributes(mesh.attributes)
add_attributes(mesh.uv_layers)
add_attributes(ob.vertex_groups)
colliding_names = [name for name, layers in attributes_by_name.items() if len(layers) >= 2]
if len(colliding_names) == 0:

View File

@ -92,6 +92,14 @@ int *BKE_id_attributes_active_color_index_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);
void BKE_id_attributes_render_color_set(struct ID *id, struct CustomDataLayer *active_layer);
CustomDataLayer *BKE_id_attributes_render_color_get(struct ID *id);
bool BKE_id_attribute_find_unique_name(struct ID *id,
const char *name,
char *outname,
CustomDataMask mask);
#ifdef __cplusplus
}
#endif

View File

@ -665,6 +665,7 @@ BLI_INLINE int BKE_mesh_origindex_mface_mpoly(const int *index_mf_to_mpoly,
}
/* ensures attribute active indices are kept up to date */
bool BKE_mesh_customdata_merge(struct Mesh *me,
AttributeDomain domain,
CustomData *src,
@ -679,22 +680,21 @@ void BKE_mesh_customdata_copy(struct Mesh *me,
eCDAllocType alloctype,
int totelem);
typedef struct CustomDataMergeState {
struct CustomData *dst;
int active_type, active_color_type, render_color_type;
char active_name[MAX_CUSTOMDATA_LAYER_NAME];
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME];
char render_color_name[MAX_CUSTOMDATA_LAYER_NAME];
} CustomDataMergeState;
void BKE_mesh_attributes_update_pre(struct Mesh *me,
AttributeDomain domain,
CustomData **r_dst,
CustomData *src,
int *active_type,
char active_name[MAX_CUSTOMDATA_LAYER_NAME],
int *active_color_type,
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME]);
CustomDataMergeState *state);
void BKE_mesh_attributes_update_post(struct Mesh *me,
AttributeDomain domain,
CustomData *dst,
CustomData *src,
int *active_type,
char active_name[MAX_CUSTOMDATA_LAYER_NAME],
int *active_color_type,
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME]);
CustomDataMergeState *state);
#ifdef __cplusplus
}
#endif

View File

@ -1050,4 +1050,4 @@ void BKE_dyntopo_remesh(DynTopoState *ds,
int steps,
PBVHTopologyUpdateMode mode);
void BKE_pbvh_bmesh_get_vcol(
struct BMVert *v, float color[4], int vcol_type, int vcol_domain, int vcol_offset);
struct BMVert *v, float color[4], int vcol_type, AttributeDomain vcol_domain, int vcol_offset);

View File

@ -35,7 +35,10 @@
#include "DNA_meshdata_types.h"
#include "DNA_pointcloud_types.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BKE_attribute.h"
#include "BKE_customdata.h"
@ -149,6 +152,48 @@ bool BKE_id_attribute_rename(ID *id,
return true;
}
typedef struct AttrUniqueData {
ID *id;
CustomDataMask mask;
} AttrUniqueData;
static bool unique_name_cb(void *arg, const char *name)
{
AttrUniqueData *data = (AttrUniqueData *)arg;
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(data->id, info);
for (AttributeDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM; domain++) {
if (!info[domain].customdata) {
continue;
}
CustomData *cdata = info[domain].customdata;
for (int i = 0; i < cdata->totlayer; i++) {
CustomDataLayer *layer = cdata->layers + i;
if ((CD_TYPE_AS_MASK(layer->type) & data->mask) && STREQ(layer->name, name)) {
return true;
}
}
}
return false;
}
bool BKE_id_attribute_find_unique_name(ID *id,
const char *name,
char *outname,
CustomDataMask mask)
{
AttrUniqueData data = {.id = id, .mask = mask};
BLI_strncpy(outname, name, MAX_CUSTOMDATA_LAYER_NAME);
return BLI_uniquename_cb(unique_name_cb, &data, NULL, '.', outname, MAX_CUSTOMDATA_LAYER_NAME);
}
ATTR_NO_OPT CustomDataLayer *BKE_id_attribute_new(
ID *id, const char *name, const int type, const AttributeDomain domain, ReportList *reports)
{
@ -162,7 +207,11 @@ ATTR_NO_OPT CustomDataLayer *BKE_id_attribute_new(
}
char uniquename[sizeof(customdata->layers->name)];
CustomData_find_unique_layer_name(customdata, type, name, uniquename);
BKE_id_attribute_find_unique_name(
id,
name,
uniquename,
((1ULL << type) & CD_MASK_PROP_ALL) ? CD_MASK_PROP_ALL : (CustomDataMask)(1ULL << type));
switch (GS(id->name)) {
case ID_ME: {
@ -496,6 +545,90 @@ 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);
return NULL;
}
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
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 (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;
}
ATTR_NO_OPT void BKE_id_attributes_render_color_set(ID *id, CustomDataLayer *active_layer)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
if (!active_layer || !ELEM(active_layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
fprintf(stderr,
"bad active color layer %p; type was %d\n",
active_layer,
active_layer ? active_layer->type : -1);
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;
return;
}
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(layer->type)) {
index++;
}
}
}
}
}
int *BKE_id_attributes_render_color_index_p(ID *id)
{
switch (GS(id->name)) {
case ID_ME: {
return &((Mesh *)id)->render_color_index;
}
default:
return NULL;
}
}
CustomData *BKE_id_attributes_iterator_next_domain(ID *id, CustomDataLayer *layers)
{
DomainInfo info[ATTR_DOMAIN_NUM];

View File

@ -2274,15 +2274,11 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)
void BKE_mesh_attributes_update_pre(Mesh *me,
AttributeDomain domain,
CustomData **r_dst,
CustomData *src,
int *active_type,
char active_name[MAX_CUSTOMDATA_LAYER_NAME],
int *active_color_type,
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME])
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;
@ -2305,64 +2301,72 @@ void BKE_mesh_attributes_update_pre(Mesh *me,
return;
}
*r_dst = dst;
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) {
*active_type = active->type;
BLI_strncpy(active_name, active->name, sizeof(active_name));
state->active_type = active->type;
BLI_strncpy(state->active_name, active->name, sizeof(state->active_name));
}
else {
*active_type = -1;
state->active_type = -1;
}
if (active_color) {
*active_color_type = active_color->type;
BLI_strncpy(active_color_name, active_color->name, sizeof(active_color_name));
state->active_color_type = active_color->type;
BLI_strncpy(state->active_color_name, active_color->name, sizeof(state->active_color_name));
}
else {
*active_color_type = -1;
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,
CustomData *dst,
CustomData *src,
int *active_type,
char active_name[MAX_CUSTOMDATA_LAYER_NAME],
int *active_color_type,
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME])
CustomDataMergeState *state)
{
int active_idx = *active_type != -1 ?
CustomData_get_named_layer_index(dst, *active_type, active_name) :
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 = *active_color_type != -1 ?
int active_color_idx = state->active_color_type != -1 ?
CustomData_get_named_layer_index(
dst, *active_color_type, active_color_name) :
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, dst->layers + active_idx);
BKE_id_attributes_active_set((ID *)me, state->dst->layers + active_idx);
}
if (active_color_idx != -1) {
BKE_id_attributes_active_set((ID *)me, dst->layers + active_idx);
BKE_id_attributes_active_color_set((ID *)me, state->dst->layers + active_color_idx);
}
else if (*active_color_type != -1) {
else if (state->active_color_type != -1) {
bool ok = false;
// layer disappeared, find a new one
for (int i = 0; i < dst->totlayer; i++) {
if (ELEM(dst->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL)) {
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_set((ID *)me, dst->layers + i);
BKE_id_attributes_active_color_set((ID *)me, state->dst->layers + i);
break;
}
}
@ -2373,7 +2377,35 @@ void BKE_mesh_attributes_update_post(Mesh *me,
for (int i = 0; i < other->totlayer; i++) {
if (ELEM(other->layers[i].type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_active_set((ID *)me, other->layers + i);
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;
}
}
@ -2391,19 +2423,19 @@ bool BKE_mesh_customdata_merge(Mesh *me,
int active_type, active_color_type;
char active_name[MAX_CUSTOMDATA_LAYER_NAME];
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME];
CustomData *dst = NULL;
CustomDataMergeState state;
BKE_mesh_attributes_update_pre(
me, domain, &dst, src, &active_type, active_name, &active_color_type, active_color_name);
me, domain, &state);
if (!dst) {
if (!state.dst) {
return false;
}
bool ret = CustomData_merge(src, dst, mask, alloctype, totelem);
bool ret = CustomData_merge(src, state.dst, mask, alloctype, totelem);
BKE_mesh_attributes_update_post(
me, domain, dst, src, &active_type, active_name, &active_color_type, active_color_name);
me, domain, &state);
return ret;
}
@ -2418,17 +2450,17 @@ void BKE_mesh_customdata_copy(Mesh *me,
int active_type, active_color_type;
char active_name[MAX_CUSTOMDATA_LAYER_NAME];
char active_color_name[MAX_CUSTOMDATA_LAYER_NAME];
CustomData *dst = NULL;
CustomDataMergeState state;
BKE_mesh_attributes_update_pre(
me, domain, &dst, src, &active_type, active_name, &active_color_type, active_color_name);
me, domain, &state);
if (!dst) {
if (!state.dst) {
return;
}
CustomData_copy(src, dst, mask, alloctype, totelem);
CustomData_copy(src, state.dst, mask, alloctype, totelem);
BKE_mesh_attributes_update_post(
me, domain, dst, src, &active_type, active_name, &active_color_type, active_color_name);
me, domain, &state);
}

View File

@ -1461,6 +1461,22 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
AttributeDomain vcol_domain;
BKE_pbvh_get_color_layer(pbvh, me, &vcol_layer, &vcol_domain);
CustomDataLayer *render_vcol_layer = BKE_id_attributes_render_color_get((ID *)me);
if (pbvh->bm && render_vcol_layer) {
AttributeDomain domain = BKE_id_attribute_domain((ID *)me, render_vcol_layer);
CustomData *cdata = domain == ATTR_DOMAIN_POINT ? &pbvh->bm->vdata : &pbvh->bm->ldata;
int idx = CustomData_get_named_layer_index(
cdata, render_vcol_layer->type, render_vcol_layer->name);
if (idx == -1) {
render_vcol_layer = NULL; /* layers hasn't been synced over yet */
}
else {
render_vcol_layer = cdata->layers + idx;
}
}
if (node->flag & PBVH_RebuildDrawBuffers) {
node->updategen++;
@ -1575,7 +1591,8 @@ static void pbvh_update_draw_buffer_cb(void *__restrict userdata,
.mat_nr = node->tri_buffers[i].mat_nr,
.active_vcol_domain = pbvh->vcol_domain,
.active_vcol_type = pbvh->vcol_type,
.active_vcol_layer = vcol_layer};
.active_vcol_layer = vcol_layer,
.render_vcol_layer = render_vcol_layer};
GPU_pbvh_bmesh_buffers_update(&args);
}
@ -1656,13 +1673,31 @@ static void pbvh_update_draw_buffers(
AttributeDomain domain;
BKE_pbvh_get_color_layer(pbvh, me, &vcol_layer, &domain);
CustomDataLayer *render_vcol_layer = BKE_id_attributes_render_color_get((ID *)me);
if (pbvh->bm && render_vcol_layer) {
AttributeDomain domain = BKE_id_attribute_domain((ID *)me, render_vcol_layer);
CustomData *cdata = domain == ATTR_DOMAIN_POINT ? &pbvh->bm->vdata : &pbvh->bm->ldata;
int idx = CustomData_get_named_layer_index(
cdata, render_vcol_layer->type, render_vcol_layer->name);
if (idx == -1) {
render_vcol_layer = NULL; /* layer hasn't been synced over yet */
}
else {
render_vcol_layer = cdata->layers + idx;
}
}
GPU_pbvh_update_attribute_names(vdata,
ldata,
GPU_pbvh_need_full_render_get(),
pbvh->flags & PBVH_FAST_DRAW,
pbvh->vcol_type,
pbvh->vcol_domain,
vcol_layer);
vcol_layer,
render_vcol_layer);
if ((update_flag & PBVH_RebuildDrawBuffers) || ELEM(pbvh->type, PBVH_GRIDS, PBVH_BMESH)) {
/* Free buffers uses OpenGL, so not in parallel. */

View File

@ -809,11 +809,11 @@ void BKE_pbvh_bmesh_regen_node_verts(PBVH *pbvh)
}
}
void BKE_pbvh_bmesh_get_vcol(
BMVert *v, float color[4], int vcol_type, int vcol_domain, int vcol_offset)
ATTR_NO_OPT void BKE_pbvh_bmesh_get_vcol(
BMVert *v, float color[4], int vcol_type, AttributeDomain vcol_domain, int vcol_offset)
{
if (vcol_domain == ATTR_DOMAIN_POINT) {
switch (vcol_offset) {
switch (vcol_type) {
case CD_PROP_COLOR:
copy_v4_v4(color, (float *)BM_ELEM_CD_GET_VOID_P(v, vcol_offset));
break;

View File

@ -1068,22 +1068,17 @@ void BM_mesh_bm_to_me(
#endif
}
int active_types[4], active_color_types[4];
CustomData *active_dsts[4];
char active_names[4][MAX_CUSTOMDATA_LAYER_NAME];
char active_color_names[4][MAX_CUSTOMDATA_LAYER_NAME];
int active_domains[4] = {
ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_CORNER, ATTR_DOMAIN_FACE};
CustomDataMergeState attr_states[4];
for (int i = 0; i < 4; i++) {
//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],
active_dsts + i,
srcdatas[i],
active_types + i,
active_names[i],
active_color_types + i,
active_color_names[i]);
attr_states+i);
}
/* Free custom data. */
@ -1140,21 +1135,16 @@ void BM_mesh_bm_to_me(
me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
for (int i = 0; i < 4; i++) {
/* 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],
active_dsts[i],
srcdatas[i],
active_types + i,
active_names[i],
active_color_types + i,
active_color_names[i]);
attr_states+i);
}
/* This is called again, 'dotess' arg is used there. */
BKE_mesh_update_customdata_pointers(me, 0);
i = 0;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
copy_v3_v3(mvert->co, v->co);

View File

@ -59,10 +59,13 @@ static void extract_vcol_init(const MeshRenderData *mr,
/* prefer the active attribute to set active color if it's a color layer */
if (actlayer && ELEM(actlayer->type, CD_PROP_COLOR, CD_MLOOPCOL) &&
ELEM(actdomain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) {
CustomData *cdata = actdomain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata;
actn = actlayer - (cdata->layers + cdata->typemap[actlayer->type]);
}
CustomDataLayer *render_layer = BKE_id_attributes_render_color_get((ID *)mr->me);
/* set up vbo format */
for (int i = 0; i < ARRAY_SIZE(vcol_types); i++) {
int type = vcol_types[i];
@ -80,7 +83,11 @@ static void extract_vcol_init(const MeshRenderData *mr,
BLI_snprintf(attr_name, sizeof(attr_name), "c%s", attr_safe_name);
GPU_vertformat_attr_add(&format, attr_name, GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
if (j == CustomData_get_render_layer(cdata, type)) {
int idx = CustomData_get_layer_index_n(cdata, type, j);
CustomDataLayer *layer = cdata->layers + idx;
if (render_layer && layer->type == render_layer->type &&
STREQ(layer->name, render_layer->name)) {
GPU_vertformat_alias_add(&format, "c");
}

View File

@ -81,7 +81,7 @@ static const EnumPropertyItem *geometry_attribute_domain_itemf(bContext *C,
return rna_enum_attribute_domain_itemf(ob->data, r_free);
}
static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
ATTR_NO_OPT static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
ID *id = ob->data;
@ -98,6 +98,10 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op)
BKE_id_attributes_active_set(id, layer);
if (ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_active_color_set(id, layer);
}
if (ob->mode == OB_MODE_SCULPT) {
BKE_sculpt_update_object_for_edit(
CTX_data_ensure_evaluated_depsgraph(C), ob, false, false, false);

View File

@ -786,9 +786,7 @@ void SCULPT_dynamic_topology_sync_layers(Object *ob, Mesh *me)
CustomData_regen_active_refs(&ss->bm->pdata);
}
if (modified) {
SCULPT_dyntopo_node_layers_update_offsets(ss, ob);
}
SCULPT_update_customdata_refs(ss, ob);
}
BMesh *BM_mesh_bm_from_me_threaded(BMesh *bm,

View File

@ -366,7 +366,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, false, totnode);
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_color_smooth_task_cb_exec, &settings);
return;
}
@ -451,7 +451,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
};
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, false, totnode);
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
BLI_task_parallel_range(0, totnode, &data, do_paint_brush_task_cb_ex, &settings);
if (brush->vcol_boundary_factor > 0.0f) {

View File

@ -68,6 +68,7 @@ typedef struct PBVHGPUBuildArgs {
bool flat_vcol;
short mat_nr, active_vcol_type, active_vcol_domain;
struct CustomDataLayer *active_vcol_layer;
struct CustomDataLayer *render_vcol_layer;
} PBVHGPUBuildArgs;
/* Build must be called once before using the other functions, used every time
@ -113,11 +114,11 @@ void GPU_pbvh_update_attribute_names(
CustomData *vdata,
CustomData *ldata,
bool need_full_render,
bool fast_mode,
bool fast_mode, // fast mode renders without vcol, uv, facesets, even mask, etc
int active_vcol_type,
int active_vcol_domain,
struct CustomDataLayer
*active_vcol_layer); // fast mode renders without vcol, uv, facesets, even mask, etc
struct CustomDataLayer *active_vcol_layer,
struct CustomDataLayer *render_vcol_layer);
void GPU_pbvh_bmesh_buffers_update(PBVHGPUBuildArgs *args);

View File

@ -365,7 +365,7 @@ static void free_cd_layers(CDAttrLayers *cdattr)
void gpu_pbvh_init()
{
GPU_pbvh_update_attribute_names(NULL, NULL, false, false, -1, -1, NULL);
GPU_pbvh_update_attribute_names(NULL, NULL, false, false, -1, -1, NULL, NULL);
}
void gpu_pbvh_exit()
@ -1323,7 +1323,8 @@ static int gpu_pbvh_bmesh_make_vcol_offs(CustomData *vdata,
bool active_only,
int active_type,
int active_domain,
CustomDataLayer *active_vcol_layer)
CustomDataLayer *active_vcol_layer,
CustomDataLayer *render_vcol_layer)
{
if (active_only) {
CustomData *cdata = active_domain == ATTR_DOMAIN_POINT ? vdata : ldata;
@ -1365,13 +1366,11 @@ static int gpu_pbvh_bmesh_make_vcol_offs(CustomData *vdata,
/* ensure render layer is last
draw cache code seems to need this
*/
int render = CustomData_get_render_layer_index(
active_domain == ATTR_DOMAIN_POINT ? vdata : ldata, active_type);
// int active = CustomData_get_active_layer_index(
// active_domain == ATTR_DOMAIN_POINT ? vdata : ldata, active_type);
for (int i = 0; i < count; i++) {
if (r_cd_vcols[i].layer_idx == render) {
CustomData *cdata = r_cd_vcols[i].domain == ATTR_DOMAIN_POINT ? vdata : ldata;
if (cdata->layers + r_cd_vcols[i].layer_idx == render_vcol_layer) {
SWAP(ColorRef, r_cd_vcols[i], r_cd_vcols[count - 1]);
break;
}
@ -1397,7 +1396,8 @@ ATTR_NO_OPT void GPU_pbvh_update_attribute_names(CustomData *vdata,
bool fast_mode,
int active_vcol_type,
int active_vcol_domain,
CustomDataLayer *active_vcol_layer)
CustomDataLayer *active_vcol_layer,
CustomDataLayer *render_vcol_layer)
{
const bool active_only = !need_full_render;
@ -1473,7 +1473,8 @@ ATTR_NO_OPT void GPU_pbvh_update_attribute_names(CustomData *vdata,
active_only,
active_vcol_type,
active_vcol_domain,
active_vcol_layer);
active_vcol_layer,
render_vcol_layer);
for (int i = 0; i < totlayer; i++) {
ColorRef *ref = vcol_layers + i;
@ -1587,7 +1588,8 @@ static void GPU_pbvh_bmesh_buffers_update_flat_vcol(GPU_PBVH_Buffers *buffers,
short mat_nr,
int active_vcol_type,
int active_vcol_domain,
CustomDataLayer *active_vcol_layer)
CustomDataLayer *active_vcol_layer,
CustomDataLayer *render_vcol_layer)
{
bool active_vcol_only = g_vbo_id.active_vcol_only;
@ -1606,7 +1608,8 @@ static void GPU_pbvh_bmesh_buffers_update_flat_vcol(GPU_PBVH_Buffers *buffers,
active_vcol_only,
active_vcol_type,
active_vcol_domain,
active_vcol_layer);
active_vcol_layer,
render_vcol_layer);
/* Count visible triangles */
tottri = gpu_bmesh_face_visible_count(tribuf, mat_nr) * 6;
@ -1778,7 +1781,8 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
short mat_nr,
int active_vcol_type,
int active_vcol_domain,
CustomDataLayer *active_vcol_layer)
CustomDataLayer *active_vcol_layer,
CustomDataLayer *render_vcol_layer)
{
bool active_vcol_only = g_vbo_id.active_vcol_only;
@ -1805,7 +1809,8 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
active_vcol_only,
active_vcol_type,
active_vcol_domain,
active_vcol_layer);
active_vcol_layer,
render_vcol_layer);
/* Count visible triangles */
tottri = gpu_bmesh_face_visible_count(tribuf, mat_nr);
@ -1956,7 +1961,8 @@ ATTR_NO_OPT void GPU_pbvh_bmesh_buffers_update(PBVHGPUBuildArgs *args)
mat_nr,
args->active_vcol_type,
args->active_vcol_domain,
args->active_vcol_layer);
args->active_vcol_layer,
args->render_vcol_layer);
return;
}
@ -1980,7 +1986,8 @@ ATTR_NO_OPT void GPU_pbvh_bmesh_buffers_update(PBVHGPUBuildArgs *args)
active_vcol_only,
args->active_vcol_type,
args->active_vcol_domain,
args->active_vcol_layer);
args->active_vcol_layer,
args->render_vcol_layer);
/* Count visible triangles */
if (buffers->smooth) {
@ -1998,7 +2005,8 @@ ATTR_NO_OPT void GPU_pbvh_bmesh_buffers_update(PBVHGPUBuildArgs *args)
mat_nr,
args->active_vcol_type,
args->active_vcol_domain,
args->active_vcol_layer);
args->active_vcol_layer,
args->render_vcol_layer);
return;
}

View File

@ -201,6 +201,7 @@ typedef struct Mesh {
and can reference a layer of type CD_PROP_COLOR or
CD_MLOOPCOL */
int active_color_index;
int render_color_index;
/* 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
@ -233,7 +234,7 @@ typedef struct Mesh {
* consistently ensure that this symmetry is maintained. */
char symmetry;
char _pad1[6];
char _pad1[2];
int face_sets_color_seed;
/* Stores the initial Face Set to be rendered white. This way the overlay can be enabled by

View File

@ -146,6 +146,105 @@ static void rna_Attribute_name_set(PointerRNA *ptr, const char *value)
BKE_id_attribute_rename(ptr->owner_id, ptr->data, value, NULL);
}
static bool rna_Attribute_active_render_get(PointerRNA *ptr)
{
ID *id = ptr->owner_id;
CustomDataLayer *layer = ptr->data;
if (!BKE_id_attributes_supported(id)) {
return false;
}
if (ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
return layer == BKE_id_attributes_render_color_get(id);
}
if (GS(id->name) != ID_ME) {
/* only meshes for now */
return false;
}
Mesh *me = (Mesh *)id;
AttributeDomain domain = BKE_id_attribute_domain(id, layer);
CustomData *cdata = NULL;
switch (domain) {
case ATTR_DOMAIN_POINT:
cdata = &me->vdata;
break;
case ATTR_DOMAIN_EDGE:
cdata = &me->edata;
break;
case ATTR_DOMAIN_CORNER:
cdata = &me->ldata;
break;
case ATTR_DOMAIN_FACE:
cdata = &me->pdata;
break;
}
if (!cdata) {
return false;
}
CustomDataLayer *base = CustomData_get_layer_index(cdata, layer->type);
return layer == base + base->active_rnd;
}
static void rna_Attribute_active_render_set(PointerRNA *ptr, bool value)
{
ID *id = ptr->owner_id;
CustomDataLayer *layer = ptr->data;
if (!value) {
return; // do nothing;
}
if (!BKE_id_attributes_supported(id)) {
return false;
}
if (GS(id->name) != ID_ME) {
/* only meshes for now */
return false;
}
Mesh *me = (Mesh *)id;
AttributeDomain domain = BKE_id_attribute_domain(id, layer);
CustomData *cdata = NULL;
switch (domain) {
case ATTR_DOMAIN_POINT:
cdata = &me->vdata;
break;
case ATTR_DOMAIN_EDGE:
cdata = &me->edata;
break;
case ATTR_DOMAIN_CORNER:
cdata = &me->ldata;
break;
case ATTR_DOMAIN_FACE:
cdata = &me->pdata;
break;
}
if (!cdata) {
return false;
}
if (ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_render_color_set(id, layer);
}
else {
CustomDataLayer *base = CustomData_get_layer_index(cdata, layer->type);
int idx = base - cdata->layers;
int newrender = layer - base;
CustomData_set_layer_render(cdata, layer->type, newrender);
}
}
static int rna_Attribute_name_editable(PointerRNA *ptr, const char **r_info)
{
CustomDataLayer *layer = ptr->data;
@ -757,6 +856,11 @@ static void rna_def_attribute(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "active_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(
prop, "rna_Attribute_active_render_get", "rna_Attribute_active_render_set");
RNA_def_property_ui_text(prop, "Active Render", "Active for render");
prop = RNA_def_property(srna, "domain", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_attribute_domain_items);
RNA_def_property_enum_funcs(

View File

@ -778,7 +778,10 @@ static int rna_MeshLoopColorLayer_data_length(PointerRNA *ptr)
static bool rna_MeshLoopColorLayer_active_render_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPCOL, 1);
CustomDataLayer *layer = (CustomDataLayer*)ptr->data;
return BKE_id_attributes_render_color_get(ptr->owner_id) == layer;
//return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPCOL, 1);
}
static bool rna_MeshLoopColorLayer_active_get(PointerRNA *ptr)
@ -788,7 +791,12 @@ static bool rna_MeshLoopColorLayer_active_get(PointerRNA *ptr)
static void rna_MeshLoopColorLayer_active_render_set(PointerRNA *ptr, bool value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPCOL, 1);
CustomDataLayer *layer = (CustomDataLayer*)ptr->data;
if (value) {
BKE_id_attributes_render_color_set(ptr->owner_id, layer);
}
// rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPCOL, 1);
}
static void rna_MeshLoopColorLayer_active_set(PointerRNA *ptr, bool value)
@ -818,7 +826,10 @@ static int rna_MeshVertColorLayer_data_length(PointerRNA *ptr)
static bool rna_MeshVertColorLayer_active_render_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_vdata(ptr), CD_PROP_COLOR, 1);
CustomDataLayer *layer = (CustomDataLayer*)ptr->data;
return BKE_id_attributes_render_color_get(ptr->owner_id) == layer;
//return rna_CustomDataLayer_active_get(ptr, rna_mesh_vdata(ptr), CD_PROP_COLOR, 1);
}
static bool rna_MeshVertColorLayer_active_get(PointerRNA *ptr)
@ -828,7 +839,11 @@ static bool rna_MeshVertColorLayer_active_get(PointerRNA *ptr)
static void rna_MeshVertColorLayer_active_render_set(PointerRNA *ptr, bool value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_vdata(ptr), value, CD_PROP_COLOR, 1);
CustomDataLayer *layer = (CustomDataLayer*)ptr->data;
if (value) {
BKE_id_attributes_render_color_set(ptr->owner_id, layer);
}
}
static void rna_MeshVertColorLayer_active_set(PointerRNA *ptr, bool value)