[Bf-blender-cvs] [5c22f28334f] temp-T96709-painting-target: Fix refreshing after load.

Jeroen Bakker noreply at git.blender.org
Wed Mar 30 11:16:50 CEST 2022


Commit: 5c22f28334fd324bf4a4ed76478979472408abb8
Author: Jeroen Bakker
Date:   Wed Mar 30 11:16:46 2022 +0200
Branches: temp-T96709-painting-target
https://developer.blender.org/rB5c22f28334fd324bf4a4ed76478979472408abb8

Fix refreshing after load.

===================================================================

M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/material.c
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenkernel/intern/paint.c
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/shader/node_shader_util.cc

===================================================================

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/intern/material.c b/source/blender/blenkernel/intern/material.c
index 0869d63300d..e1092120d06 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1376,7 +1376,7 @@ static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree,
     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, do_color_attributes)) {
+              (bNodeTree *)node->id, callback, userdata, slot_filter)) {
         return false;
       }
     }
@@ -1517,7 +1517,7 @@ void BKE_texpaint_slot_refresh_cache(Scene *scene, Material *ma, const struct Ob
 
   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, slot_filter);
 
@@ -1541,17 +1541,27 @@ void BKE_texpaint_slots_refresh_object(Scene *scene, struct Object *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;
@@ -1559,8 +1569,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, true);
+  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 e3fe5d77d63..f590f9eea97 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -3612,19 +3612,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 6f6dc1282fd..d964668f81f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1602,12 +1602,6 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
   return false;
 }
 
-static void sculpt_update_object_paint_slots(Depsgraph *depsgraph, Object *ob)
-{
-  Scene *scene = DEG_get_input_scene(depsgraph);
-  BKE_texpaint_slots_refresh_object(scene, ob);
-}
-
 /**
  * \param need_mask: So that the evaluated mesh that is returned has mask data.
  */
@@ -1624,7 +1618,6 @@ static void sculpt_update_object(Depsgraph *depsgraph,
   const Mesh *me = BKE_object_get_original_mesh(ob);
   MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
   const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
-  const bool use_paint_slots = (ob->mode & OB_MODE_SCULPT) != 0;
 
   ss->depsgraph = depsgraph;
 
@@ -1752,8 +1745,10 @@ 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) {
-    sculpt_update_object_paint_slots(depsgraph, ob);
+    BKE_texpaint_slots_refresh_object(scene, ob);
   }
 }
 
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 73539bea8ee..23ae74f1d6f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -397,6 +397,8 @@ typedef struct bNode {
 #define NODE_DO_OUTPUT_RECALC (1 << 17)
 /* A preview for the data in this node can be displayed in the spreadsheet editor. */
 #define __NODE_ACTIVE_PREVIEW (1 << 18) /* deprecated */
+/* Active node that is used to paint on. */
+#define NODE_ACTIVE_PAINT_CANVAS (1 << 19)
 
 /* node->update */
 #define NODE_UPDATE_ID 1       /* associated id data block has changed */
diff --git a/source/blender/nodes/shader/node_shader_util.cc b/source/blender/nodes/shader/node_shader_util.cc
index 16a4c5bae88..728e2760f9a 100644
--- a/source/blender/nodes/shader/node_shader_util.cc
+++ b/source/blender/nodes/shader/node_shader_util.cc
@@ -162,8 +162,21 @@ static void data_from_gpu_stack_list(ListBase *sockets, bNodeStack **ns, GPUNode
   }
 }
 
-bNode *nodeGetActiveTexture(bNodeTree *ntree)
+bool nodeSupportsActiveFlag(const bNode *node, int sub_activity)
+{
+  BLI_assert(ELEM(sub_activity, NODE_ACTIVE_TEXTURE, NODE_ACTIVE_PAINT_CANVAS));
+  switch (sub_activity) {
+    case NODE_ACTIVE_TEXTURE:
+      return node->typeinfo->nclass == NODE_CLASS_TEXTURE;
+    case NODE_ACTIVE_PAINT_CANVAS:
+      return ELEM(node->type, SH_NODE_TEX_IMAGE, SH_NODE_ATTRIBUTE);
+  }
+  return false;
+}
+
+static bNode *node_get_active(bNodeTree *ntree, int sub_activity)
 {
+  BLI_assert(ELEM(sub_activity, NODE_ACTIVE_TEXTURE, NODE_ACTIVE_PAINT_CANVAS));
   /* this is the node we texture paint and draw in textured draw */
   bNode *inactivenode = nullptr, *activetexnode = nullptr, *activegroup = nullptr;
   bool hasgroup = false;
@@ -173,14 +186,14 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
   }
 
   LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
-    if (node->flag & NODE_ACTIVE_TEXTURE) {
+    if (node->flag & sub_activity) {
       activetexnode = node;
       /* if active we can return immediately */
       if (node->flag & NODE_ACTIVE) {
         return node;
       }
     }
-    else if (!inactivenode && node->typeinfo->nclass == NODE_CLASS_TEXTURE) {
+    else if (!inactivenode && nodeSupportsActiveFlag(node, sub_activity)) {
       inactivenode = node;
     }
     else if (node->type == NODE_GROUP) {
@@ -195,7 +208,7 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
 
   /* first, check active group for textures */
   if (activegroup) {
-    bNode *tnode = nodeGetActiveTexture((bNodeTree *)activegroup->id);
+    bNode *tnode = node_get_active((bNodeTree *)activegroup->id, sub_activity);
     /* active node takes priority, so ignore any other possible nodes here */
     if (tnode) {
       return tnode;
@@ -210,8 +223,8 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
     /* node active texture node in this tree, look inside groups */
     LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
       if (node->type == NODE_GROUP) {
-        bNode *tnode = nodeGetActiveTexture((bNodeTree *)node->id);
-        if (tnode && ((tnode->flag & NODE_ACTIVE_TEXTURE) || !inactivenode)) {
+        bNode *tnode = node_get_active((bNodeTree *)node->id, sub_activity);
+        if (tnode && ((tnode->flag & sub_activity) || !inactivenode)) {
           return tnode;
         }
       }
@@ -221,6 +234,16 @@ bNode *nodeGetActiveTexture(bNodeTree *ntree)
   return inactivenode;
 }
 
+bNode *nodeGetActiveTexture(bNodeTree *ntree)
+{
+  return node_get_active(ntree, NODE_ACTIVE_TEXTURE);
+}
+
+bNode *nodeGetActivePaintCanvas(bNodeTree *ntree)
+{
+  return node_get_active(ntree, NODE_ACTIVE_PAINT_CANVAS);
+}
+
 void ntreeExecGPUNodes(bNodeTreeExec *exec, GPUMaterial *mat, bNode *output_node)
 {
   bNodeExec *nodeexec;



More information about the Bf-blender-cvs mailing list