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:
parent
7a55066b18
commit
e724479ca6
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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]
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue