Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_attribute.h1
-rw-r--r--source/blender/blenkernel/BKE_material.h4
-rw-r--r--source/blender/blenkernel/BKE_node.h8
-rw-r--r--source/blender/blenkernel/BKE_paint.h8
-rw-r--r--source/blender/blenkernel/intern/attribute.c15
-rw-r--r--source/blender/blenkernel/intern/material.c135
-rw-r--r--source/blender/blenkernel/intern/node.cc20
-rw-r--r--source/blender/blenkernel/intern/paint.c7
8 files changed, 153 insertions, 45 deletions
diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index c5aca6a9373..62469a28eb1 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -122,6 +122,7 @@ struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID *id);
void BKE_id_attributes_active_color_set(struct ID *id, struct CustomDataLayer *active_layer);
struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID *id);
void BKE_id_attributes_render_color_set(struct ID *id, struct CustomDataLayer *active_layer);
+struct CustomDataLayer *BKE_id_attributes_color_find(const struct ID *id, const char *name);
bool BKE_id_attribute_calc_unique_name(struct ID *id, const char *name, char *outname);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 0870a099c76..f38f6afff7e 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -104,7 +104,9 @@ bool BKE_object_material_slot_used(struct Object *object, short actcol);
struct Material *BKE_gpencil_material(struct Object *ob, short act);
struct MaterialGPencilStyle *BKE_gpencil_material_settings(struct Object *ob, short act);
-void BKE_texpaint_slot_refresh_cache(struct Scene *scene, struct Material *ma);
+void BKE_texpaint_slot_refresh_cache(struct Scene *scene,
+ struct Material *ma,
+ const struct Object *ob);
void BKE_texpaint_slots_refresh_object(struct Scene *scene, struct Object *ob);
struct bNode *BKE_texpaint_slot_material_find_node(struct Material *ma, short texpaint_slot);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index fa199300780..23f14f9be9d 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -770,6 +770,14 @@ void nodeClearActive(struct bNodeTree *ntree);
* Two active flags, ID nodes have special flag for buttons display.
*/
struct bNode *nodeGetActiveTexture(struct bNodeTree *ntree);
+struct bNode *nodeGetActivePaintCanvas(struct bNodeTree *ntree);
+
+/**
+ * @brief Does the given node supports the sub active flag.
+ *
+ * @param sub_active The active flag to check. NODE_ACTIVE_TEXTURE/NODE_ACTIVE_PAINT_CANVAS
+ */
+bool nodeSupportsActiveFlag(const struct bNode *node, int sub_active);
int nodeSocketIsHidden(const struct bNodeSocket *sock);
void nodeSetSocketAvailability(struct bNodeTree *ntree,
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 5633c476dc1..1b296277b8f 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -641,6 +641,14 @@ typedef struct SculptSession {
*/
char needs_flush_to_id;
+ /**
+ * Some tools follows the shading chosen by the last used tool canvas.
+ * When not set the viewport shading color would be used.
+ *
+ * NOTE: This setting is temporarily until paint mode is added.
+ */
+ bool sticky_shading_color;
+
} SculptSession;
void BKE_sculptsession_free(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c
index c3d4eb72c0d..d8c7c3c6dd7 100644
--- a/source/blender/blenkernel/intern/attribute.c
+++ b/source/blender/blenkernel/intern/attribute.c
@@ -617,6 +617,21 @@ void BKE_id_attributes_render_color_set(ID *id, CustomDataLayer *active_layer)
id, active_layer, CD_FLAG_COLOR_RENDER, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
+CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name)
+{
+ CustomDataLayer *layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT);
+ if (layer == NULL) {
+ layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER);
+ }
+ if (layer == NULL) {
+ layer = BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_POINT);
+ }
+ if (layer == NULL) {
+ layer = BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_CORNER);
+ }
+ return layer;
+}
+
void BKE_id_attribute_copy_domains_temp(short id_type,
const CustomData *vdata,
const CustomData *edata,
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 7d01a92e829..bc569956f66 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -43,6 +43,7 @@
#include "BLT_translation.h"
#include "BKE_anim_data.h"
+#include "BKE_attribute.h"
#include "BKE_brush.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
@@ -1347,21 +1348,36 @@ static bNode *nodetree_uv_node_recursive(bNode *node)
return NULL;
}
+/** Bitwise filter for updating paint slots. */
+typedef enum ePaintSlotFilter {
+ PAINT_SLOT_IMAGE = 1 << 0,
+ PAINT_SLOT_COLOR_ATTRIBUTE = 1 << 1,
+} ePaintSlotFilter;
+
typedef bool (*ForEachTexNodeCallback)(bNode *node, void *userdata);
static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree,
ForEachTexNodeCallback callback,
- void *userdata)
+ void *userdata,
+ ePaintSlotFilter slot_filter)
{
+ const bool do_image_nodes = (slot_filter & PAINT_SLOT_IMAGE) != 0;
+ const bool do_color_attributes = (slot_filter & PAINT_SLOT_COLOR_ATTRIBUTE) != 0;
LISTBASE_FOREACH (bNode *, node, &nodetree->nodes) {
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
+ if (do_image_nodes && node->typeinfo->nclass == NODE_CLASS_TEXTURE &&
node->typeinfo->type == SH_NODE_TEX_IMAGE && node->id) {
if (!callback(node, userdata)) {
return false;
}
}
+ if (do_color_attributes && node->typeinfo->type == SH_NODE_ATTRIBUTE) {
+ if (!callback(node, userdata)) {
+ return false;
+ }
+ }
else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP) && node->id) {
/* recurse into the node group and see if it contains any textures */
- if (!ntree_foreach_texnode_recursive((bNodeTree *)node->id, callback, userdata)) {
+ if (!ntree_foreach_texnode_recursive(
+ (bNodeTree *)node->id, callback, userdata, slot_filter)) {
return false;
}
}
@@ -1375,16 +1391,17 @@ static bool count_texture_nodes_cb(bNode *UNUSED(node), void *userdata)
return true;
}
-static int count_texture_nodes_recursive(bNodeTree *nodetree)
+static int count_texture_nodes_recursive(bNodeTree *nodetree, ePaintSlotFilter slot_filter)
{
int tex_nodes = 0;
- ntree_foreach_texnode_recursive(nodetree, count_texture_nodes_cb, &tex_nodes);
+ ntree_foreach_texnode_recursive(nodetree, count_texture_nodes_cb, &tex_nodes, slot_filter);
return tex_nodes;
}
struct FillTexPaintSlotsData {
bNode *active_node;
+ const Object *ob;
Material *ma;
int index;
int slot_len;
@@ -1402,21 +1419,45 @@ static bool fill_texpaint_slots_cb(bNode *node, void *userdata)
ma->paint_active_slot = index;
}
- ma->texpaintslot[index].ima = (Image *)node->id;
- ma->texpaintslot[index].interp = ((NodeTexImage *)node->storage)->interpolation;
+ switch (node->type) {
+ case SH_NODE_TEX_IMAGE: {
+ TexPaintSlot *slot = &ma->texpaintslot[index];
+ slot->ima = (Image *)node->id;
+ slot->interp = ((NodeTexImage *)node->storage)->interpolation;
+ /* for new renderer, we need to traverse the treeback in search of a UV node */
+ bNode *uvnode = nodetree_uv_node_recursive(node);
- /* for new renderer, we need to traverse the treeback in search of a UV node */
- bNode *uvnode = nodetree_uv_node_recursive(node);
+ if (uvnode) {
+ NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
+ slot->uvname = storage->uv_map;
+ /* set a value to index so UI knows that we have a valid pointer for the mesh */
+ slot->valid = true;
+ }
+ else {
+ /* just invalidate the index here so UV map does not get displayed on the UI */
+ slot->valid = false;
+ }
+ break;
+ }
- if (uvnode) {
- NodeShaderUVMap *storage = (NodeShaderUVMap *)uvnode->storage;
- ma->texpaintslot[index].uvname = storage->uv_map;
- /* set a value to index so UI knows that we have a valid pointer for the mesh */
- ma->texpaintslot[index].valid = true;
- }
- else {
- /* just invalidate the index here so UV map does not get displayed on the UI */
- ma->texpaintslot[index].valid = false;
+ case SH_NODE_ATTRIBUTE: {
+ TexPaintSlot *slot = &ma->texpaintslot[index];
+ NodeShaderAttribute *storage = node->storage;
+ slot->attribute_name = storage->name;
+ if (storage->type == SHD_ATTRIBUTE_GEOMETRY) {
+ const Mesh *mesh = (const Mesh *)fill_data->ob->data;
+ CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh->id, storage->name);
+ slot->valid = layer != NULL;
+ }
+
+ /* Do not show unsupported attributes. */
+ if (!slot->valid) {
+ slot->attribute_name = NULL;
+ fill_data->index--;
+ }
+
+ break;
+ }
}
return fill_data->index != fill_data->slot_len;
@@ -1424,14 +1465,26 @@ static bool fill_texpaint_slots_cb(bNode *node, void *userdata)
static void fill_texpaint_slots_recursive(bNodeTree *nodetree,
bNode *active_node,
+ const Object *ob,
Material *ma,
- int slot_len)
+ int slot_len,
+ ePaintSlotFilter slot_filter)
+{
+ struct FillTexPaintSlotsData fill_data = {active_node, ob, ma, 0, slot_len};
+ ntree_foreach_texnode_recursive(nodetree, fill_texpaint_slots_cb, &fill_data, slot_filter);
+}
+
+/** Check which type of paint slots should be filled for the given object. */
+static ePaintSlotFilter material_paint_slot_filter(const struct Object *ob)
{
- struct FillTexPaintSlotsData fill_data = {active_node, ma, 0, slot_len};
- ntree_foreach_texnode_recursive(nodetree, fill_texpaint_slots_cb, &fill_data);
+ ePaintSlotFilter slot_filter = PAINT_SLOT_IMAGE;
+ if (ob->mode == OB_MODE_SCULPT && U.experimental.use_sculpt_texture_paint) {
+ slot_filter |= PAINT_SLOT_COLOR_ATTRIBUTE;
+ }
+ return slot_filter;
}
-void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
+void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma, const struct Object *ob)
{
int count = 0;
@@ -1439,6 +1492,8 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
return;
}
+ const ePaintSlotFilter slot_filter = material_paint_slot_filter(ob);
+
/* COW needed when adding texture slot on an object with no materials. */
DEG_id_tag_update(&ma->id, ID_RECALC_SHADING | ID_RECALC_COPY_ON_WRITE);
@@ -1460,7 +1515,7 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
return;
}
- count = count_texture_nodes_recursive(ma->nodetree);
+ count = count_texture_nodes_recursive(ma->nodetree, slot_filter);
if (count == 0) {
ma->paint_active_slot = 0;
@@ -1470,9 +1525,9 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma)
ma->texpaintslot = MEM_callocN(sizeof(*ma->texpaintslot) * count, "texpaint_slots");
- bNode *active_node = nodeGetActiveTexture(ma->nodetree);
+ bNode *active_node = nodeGetActivePaintCanvas(ma->nodetree);
- fill_texpaint_slots_recursive(ma->nodetree, active_node, ma, count);
+ fill_texpaint_slots_recursive(ma->nodetree, active_node, ob, ma, count, slot_filter);
ma->tot_slots = count;
@@ -1489,22 +1544,32 @@ void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *ob)
{
for (int i = 1; i < ob->totcol + 1; i++) {
Material *ma = BKE_object_material_get(ob, i);
- BKE_texpaint_slot_refresh_cache(scene, ma);
+ BKE_texpaint_slot_refresh_cache(scene, ma, ob);
}
}
struct FindTexPaintNodeData {
- Image *ima;
+ TexPaintSlot *slot;
bNode *r_node;
};
static bool texpaint_slot_node_find_cb(bNode *node, void *userdata)
{
struct FindTexPaintNodeData *find_data = userdata;
- Image *ima = (Image *)node->id;
- if (find_data->ima == ima) {
- find_data->r_node = node;
- return false;
+ if (find_data->slot->ima && node->type == SH_NODE_TEX_IMAGE) {
+ Image *node_ima = (Image *)node->id;
+ if (find_data->slot->ima == node_ima) {
+ find_data->r_node = node;
+ return false;
+ }
+ }
+
+ if (find_data->slot->attribute_name && node->type == SH_NODE_ATTRIBUTE) {
+ NodeShaderAttribute *storage = node->storage;
+ if (STREQLEN(find_data->slot->attribute_name, storage->name, sizeof(storage->name))) {
+ find_data->r_node = node;
+ return false;
+ }
}
return true;
@@ -1512,8 +1577,12 @@ static bool texpaint_slot_node_find_cb(bNode *node, void *userdata)
bNode *BKE_texpaint_slot_material_find_node(Material *ma, short texpaint_slot)
{
- struct FindTexPaintNodeData find_data = {ma->texpaintslot[texpaint_slot].ima, NULL};
- ntree_foreach_texnode_recursive(ma->nodetree, texpaint_slot_node_find_cb, &find_data);
+ TexPaintSlot *slot = &ma->texpaintslot[texpaint_slot];
+ struct FindTexPaintNodeData find_data = {slot, NULL};
+ ntree_foreach_texnode_recursive(ma->nodetree,
+ texpaint_slot_node_find_cb,
+ &find_data,
+ PAINT_SLOT_IMAGE | PAINT_SLOT_COLOR_ATTRIBUTE);
return find_data.r_node;
}
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 76b66beaf0d..7efdd855a04 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -3610,19 +3610,17 @@ void nodeClearActive(bNodeTree *ntree)
void nodeSetActive(bNodeTree *ntree, bNode *node)
{
- /* make sure only one node is active, and only one per ID type */
- LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
- tnode->flag &= ~NODE_ACTIVE;
+ const bool is_paint_canvas = nodeSupportsActiveFlag(node, NODE_ACTIVE_PAINT_CANVAS);
+ const bool is_texture_class = nodeSupportsActiveFlag(node, NODE_ACTIVE_TEXTURE);
+ int flags_to_set = NODE_ACTIVE;
+ SET_FLAG_FROM_TEST(flags_to_set, is_paint_canvas, NODE_ACTIVE_PAINT_CANVAS);
+ SET_FLAG_FROM_TEST(flags_to_set, is_texture_class, NODE_ACTIVE_TEXTURE);
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
- tnode->flag &= ~NODE_ACTIVE_TEXTURE;
- }
- }
-
- node->flag |= NODE_ACTIVE;
- if (node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
- node->flag |= NODE_ACTIVE_TEXTURE;
+ /* Make sure only one node is active per node tree. */
+ LISTBASE_FOREACH (bNode *, tnode, &ntree->nodes) {
+ tnode->flag &= ~flags_to_set;
}
+ node->flag |= flags_to_set;
}
int nodeSocketIsHidden(const bNodeSocket *sock)
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 8e87f6ea243..eb3f47760fc 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -42,6 +42,7 @@
#include "BKE_key.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_runtime.h"
@@ -1769,6 +1770,12 @@ static void sculpt_update_object(Depsgraph *depsgraph,
}
}
}
+
+ /* We could be more precise when we have access to the active tool. */
+ const bool use_paint_slots = (ob->mode & OB_MODE_SCULPT) != 0;
+ if (use_paint_slots) {
+ BKE_texpaint_slots_refresh_object(scene, ob);
+ }
}
void BKE_sculpt_update_object_before_eval(Object *ob)