Sculpt-dev: sculpt colors stuff

* Mask by color now works for dyntopo.
* Attribute and vertex color lists in the UI
  now hide temporary CD layers.
* Added a specific op for removing vertex color
  attributes.
* Fixed various bugs.
This commit is contained in:
Joseph Eagar 2021-11-17 03:09:37 -08:00
parent 7a55066b18
commit e724479ca6
14 changed files with 124 additions and 36 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -450,6 +450,7 @@ class MESH_UL_color_attributes(UIList):
for item in attrs:
bad = item.domain not in ["POINT", "CORNER"]
bad = bad or item.data_type not in ["FLOAT_COLOR", "BYTE_COLOR"]
bad = bad or item.temporary
#if not bad:
#print(bad, idx, item.name, item.domain, item.data_type)
@ -501,7 +502,7 @@ class DATA_PT_vertex_colors(MeshButtonsPanel, Panel):
col = row.column(align=True)
col.operator("geometry.color_attribute_add", icon='ADD', text="")
col.operator("geometry.attribute_remove", icon='REMOVE', text="")
col.operator("geometry.color_attribute_remove", icon='REMOVE', text="")
active = mesh.attributes.active
@ -616,6 +617,20 @@ class MESH_UL_attributes(UIList):
'CORNER': "Face Corner",
}
def filter_items(self, context, data, property):
attrs = getattr(data, property)
ret = []
idxs = []
idx = 0
for item in attrs:
ret.append(self.bitflag_filter_item if not item.temporary else 0)
idxs.append(idx)
idx += 1
return ret, idxs
def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index):
data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type]

View File

@ -99,7 +99,7 @@ void BKE_id_attributes_active_set(struct ID *id, struct CustomDataLayer *layer);
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);
CustomDataLayer *BKE_id_attribute_from_index(const struct ID *id, int lookup_index, const AttributeDomainMask domain_mask);
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);

View File

@ -301,7 +301,9 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id,
return NULL;
}
CustomDataLayer *BKE_id_attribute_from_index(const ID *id, int lookup_index)
CustomDataLayer *BKE_id_attribute_from_index(const ID *id,
int lookup_index,
const AttributeDomainMask domain_mask)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
@ -310,7 +312,7 @@ CustomDataLayer *BKE_id_attribute_from_index(const ID *id, int lookup_index)
for (AttributeDomain domain = 0; domain < ATTR_DOMAIN_NUM; domain++) {
CustomData *customdata = info[domain].customdata;
if (!customdata) {
if (!customdata || !((1 << (int)domain) & domain_mask)) {
continue;
}
@ -486,7 +488,7 @@ void BKE_id_attributes_active_color_set(ID *id, CustomDataLayer *active_layer)
{
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(id);
if (!ref) {
if (!ref || !ref->type) {
fprintf(stderr, "%s: vertex colors not supported for this type\n", __func__);
return;
}
@ -535,7 +537,7 @@ CustomDataLayer *BKE_id_attributes_render_color_get(ID *id)
{
AttributeRef *ref = BKE_id_attributes_render_color_ref_p(id);
if (!ref) {
if (!ref || !ref->type) {
fprintf(stderr, "%s: vertex colors not supported for this type\n", __func__);
return NULL;
}

View File

@ -153,6 +153,9 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
/* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
mesh_dst->key->from = &mesh_dst->id;
}
mesh_dst->attr_color_active = mesh_src->attr_color_active;
mesh_dst->attr_color_render = mesh_src->attr_color_render;
}
static void mesh_free_data(ID *id)
@ -1016,6 +1019,9 @@ void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
me_dst->face_sets_color_seed = me_src->face_sets_color_seed;
me_dst->face_sets_color_default = me_src->face_sets_color_default;
me_dst->attr_color_active = me_src->attr_color_active;
me_dst->attr_color_render = me_src->attr_color_render;
/* Copy texture space. */
me_dst->texflag = me_src->texflag;
copy_v3_v3(me_dst->loc, me_src->loc);

View File

@ -24,6 +24,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
#include "BKE_object.h"
#include "extract_mesh.h"
@ -33,7 +34,7 @@ namespace blender::draw {
/** \name Extract VCol
* \{ */
static void extract_vcol_init(const MeshRenderData *mr,
ATTR_NO_OPT static void extract_vcol_init(const MeshRenderData *mr,
struct MeshBatchCache *cache,
void *buf,
void *UNUSED(tls_data))
@ -41,7 +42,7 @@ static void extract_vcol_init(const MeshRenderData *mr,
GPUVertBuf *vbo = static_cast<GPUVertBuf *>(buf);
GPUVertFormat format = {0};
GPU_vertformat_deinterleave(&format);
CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata;
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;

View File

@ -742,6 +742,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
brush.particle.puff
brush.particle.smooth
brush.particle.weight
brush.sculpt.array
brush.sculpt.blob
brush.sculpt.boundary
brush.sculpt.clay
@ -755,6 +756,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
brush.sculpt.draw_face_sets
brush.sculpt.draw_sharp
brush.sculpt.elastic_deform
brush.sculpt.fairing
brush.sculpt.fill
brush.sculpt.flatten
brush.sculpt.grab
@ -763,16 +765,20 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
brush.sculpt.mask
brush.sculpt.multiplane_scrape
brush.sculpt.nudge
brush.sculpt.paint
brush.sculpt.pinch
brush.sculpt.pose
brush.sculpt.rotate
brush.sculpt.scene_project
brush.sculpt.scrape
brush.sculpt.simplify
brush.sculpt.smear
brush.sculpt.smooth
brush.sculpt.snake_hook
brush.sculpt.thumb
brush.sculpt.topology
brush.sculpt.twist
brush.sculpt.vcol_boundary
brush.uv_sculpt.grab
brush.uv_sculpt.pinch
brush.uv_sculpt.relax
@ -864,6 +870,8 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES
ops.sculpt.lasso_trim
ops.sculpt.line_mask
ops.sculpt.line_project
ops.sculpt.mask_by_color
ops.sculpt.mask_select
ops.sculpt.mesh_filter
ops.sequencer.blade
ops.transform.bone_envelope

View File

@ -240,3 +240,58 @@ void GEOMETRY_OT_attribute_remove(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
ID *id = ob->data;
CustomDataLayer *layer = BKE_id_attributes_active_color_get(id);
if (layer == NULL) {
return OPERATOR_CANCELLED;
}
if (!BKE_id_attribute_remove(id, layer, op->reports)) {
return OPERATOR_CANCELLED;
}
int *active_index = BKE_id_attributes_active_index_p(id);
if (*active_index > 0) {
*active_index -= 1;
}
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
return OPERATOR_FINISHED;
}
static bool geometry_color_attributes_remove_poll(bContext *C)
{
if (!geometry_attributes_poll(C)) {
return false;
}
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
if (BKE_id_attributes_active_color_get(data) != NULL) {
return true;
}
return false;
}
void GEOMETRY_OT_color_attribute_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Color Attribute";
ot->description = "Remove color attribute from geometry";
ot->idname = "GEOMETRY_OT_color_attribute_remove";
/* api callbacks */
ot->exec = geometry_color_attribute_remove_exec;
ot->poll = geometry_color_attributes_remove_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}

View File

@ -29,3 +29,5 @@ struct wmOperatorType;
void GEOMETRY_OT_attribute_add(struct wmOperatorType *ot);
void GEOMETRY_OT_color_attribute_add(struct wmOperatorType *ot);
void GEOMETRY_OT_attribute_remove(struct wmOperatorType *ot);
void GEOMETRY_OT_color_attribute_remove(struct wmOperatorType *ot);

View File

@ -34,4 +34,5 @@ void ED_operatortypes_geometry(void)
WM_operatortype_append(GEOMETRY_OT_attribute_add);
WM_operatortype_append(GEOMETRY_OT_color_attribute_add);
WM_operatortype_append(GEOMETRY_OT_attribute_remove);
WM_operatortype_append(GEOMETRY_OT_color_attribute_remove);
}

View File

@ -1020,11 +1020,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven
}
/* Color data is not available in Multires. */
if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
return OPERATOR_CANCELLED;
}
if (!ss->vcol) {
if (!ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_BMESH)) {
return OPERATOR_CANCELLED;
}

View File

@ -214,6 +214,12 @@ static void rna_Attribute_active_render_set(PointerRNA *ptr, bool value)
return;
}
if (ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) {
BKE_id_attributes_render_color_set(id, layer);
return;
}
Mesh *me = (Mesh *)id;
AttributeDomain domain = BKE_id_attribute_domain(id, layer);
CustomData *cdata;
@ -235,18 +241,13 @@ static void rna_Attribute_active_render_set(PointerRNA *ptr, bool value)
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);
int idx = CustomData_get_layer_index(cdata, layer->type);
if (idx != -1) {
CustomDataLayer *base = cdata->layers + idx;
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);
}
}
@ -542,10 +543,8 @@ static int rna_AttributeGroup_active_color_index_get(PointerRNA *ptr)
{
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(ptr->owner_id);
return ref ? BKE_id_attribute_index_from_ref(ptr->owner_id,
ref,
ATTR_DOMAIN_MASK_ALL,
CD_MASK_PROP_ALL) :
return ref ? BKE_id_attribute_index_from_ref(
ptr->owner_id, ref, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL) :
0;
}
@ -554,11 +553,8 @@ static void rna_AttributeGroup_active_color_index_set(PointerRNA *ptr, int value
ID *id = ptr->owner_id;
AttributeRef *ref = BKE_id_attributes_active_color_ref_p(ptr->owner_id);
if (!ref || !BKE_id_attribute_ref_from_index(id,
value,
ATTR_DOMAIN_MASK_ALL,
CD_MASK_PROP_ALL,
ref)) {
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);
}
}
@ -567,8 +563,9 @@ 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, ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER, CD_MASK_PROP_COLOR|CD_MASK_MLOOPCOL);
*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;
@ -580,8 +577,8 @@ static void rna_AttributeGroup_update_active_color(Main *bmain, Scene *scene, Po
/* cheating way for importers to avoid slow updates */
if (id->us > 0) {
// DEG_id_tag_update(id, 0);
// WM_main_add_notifier(NC_GEOM | ND_DATA, id);
DEG_id_tag_update(id, 0);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
}
}
#else
@ -871,6 +868,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, "temporary", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CD_FLAG_TEMPORARY);
RNA_def_property_ui_text(prop, "Temporary", "Layer is temporary");
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");