UI: Add color attribute create to canvas selector
The purpose of this patch is to add the option to create a color attribute paint slot from the canvas selector when in material mode. See the discussion here: T97346 --- |Add Image Paint Slot|Add Color Attribute Paint Slot| |{F13016547 size=full}|{F13032911 size=full}| Reviewed By: HooglyBoogly, joeedh Differential Revision: https://developer.blender.org/D14724
This commit is contained in:
parent
90298c24a2
commit
b96cdbcf7a
Notes:
blender-bot
2023-02-14 08:38:14 +01:00
Referenced by commit 719c86c0a6
, Fix: compiler warnings due to recent commit
Referenced by issue #97346, Canvas Selector UX: Add option to create a color attribute in material mode.
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -35,12 +36,17 @@
|
|||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_defs.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_enums.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_brush.h"
|
||||
#include "BKE_camera.h"
|
||||
#include "BKE_colorband.h"
|
||||
|
@ -61,6 +67,8 @@
|
|||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
@ -76,12 +84,18 @@
|
|||
#include "GPU_capabilities.h"
|
||||
#include "GPU_init_exit.h"
|
||||
|
||||
#include "NOD_shader.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
|
||||
|
@ -6459,6 +6473,38 @@ static Image *proj_paint_image_create(wmOperator *op, Main *bmain, bool is_data)
|
|||
return ima;
|
||||
}
|
||||
|
||||
static CustomDataLayer *proj_paint_color_attribute_create(wmOperator *op, Object *ob)
|
||||
{
|
||||
char name[MAX_NAME] = "";
|
||||
float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
AttributeDomain domain = ATTR_DOMAIN_POINT;
|
||||
CustomDataType type = CD_PROP_COLOR;
|
||||
|
||||
if (op) {
|
||||
RNA_string_get(op->ptr, "name", name);
|
||||
RNA_float_get_array(op->ptr, "color", color);
|
||||
domain = (AttributeDomain)RNA_enum_get(op->ptr, "domain");
|
||||
type = (CustomDataType)RNA_enum_get(op->ptr, "data_type");
|
||||
}
|
||||
|
||||
ID *id = (ID *)ob->data;
|
||||
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, op->reports);
|
||||
|
||||
if (!layer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BKE_id_attributes_active_color_set(id, layer);
|
||||
|
||||
if (!BKE_id_attributes_render_color_get(id)) {
|
||||
BKE_id_attributes_render_color_set(id, layer);
|
||||
}
|
||||
|
||||
BKE_object_attributes_active_color_fill(ob, color, false);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
static void proj_paint_default_color(wmOperator *op, int type, Material *ma)
|
||||
{
|
||||
if (RNA_struct_property_is_set(op->ptr, "color")) {
|
||||
|
@ -6516,6 +6562,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
Material *ma;
|
||||
Image *ima = NULL;
|
||||
CustomDataLayer *layer = NULL;
|
||||
|
||||
if (!ob) {
|
||||
return false;
|
||||
|
@ -6528,7 +6575,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
|||
int type = RNA_enum_get(op->ptr, "type");
|
||||
bool is_data = (type > LAYER_BASE_COLOR);
|
||||
|
||||
bNode *imanode;
|
||||
bNode *new_node;
|
||||
bNodeTree *ntree = ma->nodetree;
|
||||
|
||||
if (!ntree) {
|
||||
|
@ -6538,17 +6585,33 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
|||
|
||||
ma->use_nodes = true;
|
||||
|
||||
/* try to add an image node */
|
||||
imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE);
|
||||
const ePaintCanvasSource slot_type = ob->mode == OB_MODE_SCULPT ?
|
||||
(ePaintCanvasSource)RNA_enum_get(op->ptr,
|
||||
"slot_type") :
|
||||
PAINT_CANVAS_SOURCE_IMAGE;
|
||||
|
||||
ima = proj_paint_image_create(op, bmain, is_data);
|
||||
imanode->id = &ima->id;
|
||||
|
||||
nodeSetActive(ntree, imanode);
|
||||
/* Create a new node. */
|
||||
switch (slot_type) {
|
||||
case PAINT_CANVAS_SOURCE_IMAGE: {
|
||||
new_node = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE);
|
||||
ima = proj_paint_image_create(op, bmain, is_data);
|
||||
new_node->id = &ima->id;
|
||||
break;
|
||||
}
|
||||
case PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE: {
|
||||
new_node = nodeAddStaticNode(C, ntree, SH_NODE_ATTRIBUTE);
|
||||
if (layer = proj_paint_color_attribute_create(op, ob)) {
|
||||
BLI_strncpy_utf8(
|
||||
&((NodeShaderAttribute *)new_node->storage)->name, &layer->name, MAX_NAME);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
nodeSetActive(ntree, new_node);
|
||||
|
||||
/* Connect to first available principled BSDF node. */
|
||||
bNode *in_node = ntreeFindType(ntree, SH_NODE_BSDF_PRINCIPLED);
|
||||
bNode *out_node = imanode;
|
||||
bNode *out_node = new_node;
|
||||
|
||||
if (in_node != NULL) {
|
||||
bNodeSocket *out_sock = nodeFindSocket(out_node, SOCK_OUT, "Color");
|
||||
|
@ -6611,6 +6674,11 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
|||
BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
|
||||
}
|
||||
if (layer) {
|
||||
BKE_texpaint_slot_refresh_cache(scene, ma, ob);
|
||||
DEG_id_tag_update(ob->data, ID_RECALC_GEOMETRY);
|
||||
WM_main_add_notifier(NC_GEOM | ND_DATA, ob->data);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&ntree->id, 0);
|
||||
DEG_id_tag_update(&ma->id, ID_RECALC_SHADING);
|
||||
|
@ -6678,13 +6746,48 @@ static int texture_paint_add_texture_paint_slot_invoke(bContext *C,
|
|||
int type = get_texture_layer_type(op, "type");
|
||||
proj_paint_default_color(op, type, ma);
|
||||
|
||||
char imagename[MAX_ID_NAME - 2];
|
||||
get_default_texture_layer_name_for_object(ob, type, (char *)&imagename, sizeof(imagename));
|
||||
RNA_string_set(op->ptr, "name", imagename);
|
||||
char name[MAX_NAME];
|
||||
get_default_texture_layer_name_for_object(ob, type, (char *)&name, sizeof(name));
|
||||
RNA_string_set(op->ptr, "name", name);
|
||||
|
||||
return WM_operator_props_dialog_popup(C, op, 300);
|
||||
}
|
||||
|
||||
static void texture_paint_add_texture_paint_slot_ui(bContext *C, wmOperator *op)
|
||||
{
|
||||
uiLayout *layout = op->layout;
|
||||
uiLayoutSetPropSep(layout, true);
|
||||
uiLayoutSetPropDecorate(layout, false);
|
||||
Object *ob = ED_object_active_context(C);
|
||||
ePaintCanvasSource slot_type = PAINT_CANVAS_SOURCE_IMAGE;
|
||||
|
||||
if (ob->mode == OB_MODE_SCULPT) {
|
||||
slot_type = (ePaintCanvasSource)RNA_enum_get(op->ptr, "slot_type");
|
||||
uiItemR(layout, op->ptr, "slot_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
uiItemR(layout, op->ptr, "name", 0, NULL, ICON_NONE);
|
||||
|
||||
switch (slot_type) {
|
||||
case PAINT_CANVAS_SOURCE_IMAGE: {
|
||||
uiLayout *col = uiLayoutColumn(layout, true);
|
||||
uiItemR(col, op->ptr, "width", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, op->ptr, "height", 0, NULL, ICON_NONE);
|
||||
|
||||
uiItemR(layout, op->ptr, "alpha", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, op->ptr, "generated_type", 0, NULL, ICON_NONE);
|
||||
uiItemR(layout, op->ptr, "float", 0, NULL, ICON_NONE);
|
||||
break;
|
||||
}
|
||||
case PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE:
|
||||
uiItemR(layout, op->ptr, "domain", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
||||
uiItemR(layout, op->ptr, "data_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
||||
break;
|
||||
}
|
||||
|
||||
uiItemR(layout, op->ptr, "color", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
#define IMA_DEF_NAME N_("Untitled")
|
||||
|
||||
void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot)
|
||||
|
@ -6692,40 +6795,92 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot)
|
|||
PropertyRNA *prop;
|
||||
static float default_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
static const EnumPropertyItem slot_type_items[3] = {
|
||||
{PAINT_CANVAS_SOURCE_IMAGE, "IMAGE", 0, "Image", ""},
|
||||
{PAINT_CANVAS_SOURCE_COLOR_ATTRIBUTE, "COLOR_ATTRIBUTE", 0, "Color Attribute", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem domain_items[3] = {
|
||||
{ATTR_DOMAIN_POINT, "POINT", 0, "Vertex", ""},
|
||||
{ATTR_DOMAIN_CORNER, "CORNER", 0, "Face Corner", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem attribute_type_items[3] = {
|
||||
{CD_PROP_COLOR, "COLOR", 0, "Color", ""},
|
||||
{CD_PROP_BYTE_COLOR, "BYTE_COLOR", 0, "Byte Color", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Add Texture Paint Slot";
|
||||
ot->description = "Add a texture paint slot";
|
||||
ot->name = "Add Paint Slot";
|
||||
ot->description = "Add a paint slot";
|
||||
ot->idname = "PAINT_OT_add_texture_paint_slot";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = texture_paint_add_texture_paint_slot_invoke;
|
||||
ot->exec = texture_paint_add_texture_paint_slot_exec;
|
||||
ot->poll = ED_operator_object_active_editable_mesh;
|
||||
ot->ui = texture_paint_add_texture_paint_slot_ui;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop = RNA_def_enum(ot->srna, "type", layer_type_items, 0, "Type", "Merge method to use");
|
||||
/* Shared Properties */
|
||||
prop = RNA_def_enum(ot->srna,
|
||||
"type",
|
||||
layer_type_items,
|
||||
0,
|
||||
"Material Layer Type",
|
||||
"Material layer type of new paint slot");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN);
|
||||
RNA_def_string(ot->srna, "name", IMA_DEF_NAME, MAX_ID_NAME - 2, "Name", "Image data-block name");
|
||||
prop = RNA_def_int(ot->srna, "width", 1024, 1, INT_MAX, "Width", "Image width", 1, 16384);
|
||||
RNA_def_property_subtype(prop, PROP_PIXEL);
|
||||
prop = RNA_def_int(ot->srna, "height", 1024, 1, INT_MAX, "Height", "Image height", 1, 16384);
|
||||
RNA_def_property_subtype(prop, PROP_PIXEL);
|
||||
|
||||
prop = RNA_def_enum(
|
||||
ot->srna, "slot_type", slot_type_items, 0, "Slot Type", "Type of new paint slot");
|
||||
|
||||
prop = RNA_def_string(
|
||||
ot->srna, "name", IMA_DEF_NAME, MAX_NAME, "Name", "Name for new paint slot source");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_float_color(
|
||||
ot->srna, "color", 4, NULL, 0.0f, FLT_MAX, "Color", "Default fill color", 0.0f, 1.0f);
|
||||
RNA_def_property_subtype(prop, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_float_array_default(prop, default_color);
|
||||
|
||||
/* Image Properties */
|
||||
prop = RNA_def_int(ot->srna, "width", 1024, 1, INT_MAX, "Width", "Image width", 1, 16384);
|
||||
RNA_def_property_subtype(prop, PROP_PIXEL);
|
||||
|
||||
prop = RNA_def_int(ot->srna, "height", 1024, 1, INT_MAX, "Height", "Image height", 1, 16384);
|
||||
RNA_def_property_subtype(prop, PROP_PIXEL);
|
||||
|
||||
RNA_def_boolean(ot->srna, "alpha", true, "Alpha", "Create an image with an alpha channel");
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"generated_type",
|
||||
rna_enum_image_generated_type_items,
|
||||
IMA_GENTYPE_BLANK,
|
||||
"Generated Type",
|
||||
"Fill the image with a grid for UV map testing");
|
||||
|
||||
RNA_def_boolean(
|
||||
ot->srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth");
|
||||
|
||||
/* Color Attribute Properties */
|
||||
RNA_def_enum(ot->srna,
|
||||
"domain",
|
||||
domain_items,
|
||||
ATTR_DOMAIN_POINT,
|
||||
"Domain",
|
||||
"Type of element that attribute is stored on");
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"data_type",
|
||||
attribute_type_items,
|
||||
CD_PROP_COLOR,
|
||||
"Data Type",
|
||||
"Type of data stored in attribute");
|
||||
}
|
||||
|
||||
static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
|
Loading…
Reference in New Issue