[Bf-blender-cvs] [6a8bd6e598c] temp-T96709-painting-target: Color attribute switching.

Jeroen Bakker noreply at git.blender.org
Fri Mar 25 15:25:35 CET 2022


Commit: 6a8bd6e598ccb75b5bafc661da7d7da8baebea14
Author: Jeroen Bakker
Date:   Fri Mar 25 15:25:26 2022 +0100
Branches: temp-T96709-painting-target
https://developer.blender.org/rB6a8bd6e598ccb75b5bafc661da7d7da8baebea14

Color attribute switching.

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/editors/include/ED_paint.h
M	source/blender/editors/sculpt_paint/paint_canvas_material.cc
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_sculpt_paint.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 3eb82e57ceb..e051650e117 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -2255,7 +2255,7 @@ class VIEW3D_PT_tools_paint_canvas(View3DPanel, Panel):
                 layout.template_list("MESH_UL_vcols", "vcols", me, "vertex_colors", me.vertex_colors, "active_index", rows=2)
 
             case 'MATERIAL':
-                layout.prop(settings, "canvas")
+                layout.prop(ob, "paint_canvas")
 
             case 'IMAGE':
                 layout.template_ID(settings, "image", new="image.new", open="image.open")
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 8ab89b6c244..1d12affc43b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -620,6 +620,11 @@ typedef struct SculptSession {
       struct MDeformVert *dvert_prev;
     } wpaint;
 
+    struct {
+      uint16_t material_slot;
+      uint16_t resource_index;
+    } paint;
+
     /* TODO: identify sculpt-only fields */
     // struct { ... } sculpt;
   } mode;
diff --git a/source/blender/editors/include/ED_paint.h b/source/blender/editors/include/ED_paint.h
index abaa701bf42..bf3ada80188 100644
--- a/source/blender/editors/include/ED_paint.h
+++ b/source/blender/editors/include/ED_paint.h
@@ -110,13 +110,9 @@ void ED_paintcurve_undo_push_end(struct bContext *C);
 void ED_paintcurve_undosys_type(struct UndoType *ut);
 
 /* paint_canvas_material.cc */
-int ED_paint_canvas_material_get(const struct bContext *C,
-                                 const struct PaintModeSettings *settings);
-void ED_paint_canvas_material_set(struct bContext *C,
-                                  const struct PaintModeSettings *settings,
-                                  int new_value);
-void ED_paint_canvas_material_itemf(const struct bContext *C,
-                                    const struct PaintModeSettings *settings,
+int ED_paint_canvas_material_get(struct Object *ob);
+void ED_paint_canvas_material_set(struct Object *ob, int new_value);
+void ED_paint_canvas_material_itemf(struct Object *ob,
                                     struct EnumPropertyItem **r_items,
                                     int *r_totitem);
 
diff --git a/source/blender/editors/sculpt_paint/paint_canvas_material.cc b/source/blender/editors/sculpt_paint/paint_canvas_material.cc
index 6349dae68c7..0ed6841ab6b 100644
--- a/source/blender/editors/sculpt_paint/paint_canvas_material.cc
+++ b/source/blender/editors/sculpt_paint/paint_canvas_material.cc
@@ -1,5 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
+#include <optional>
+
 #include "ED_paint.h"
 
 #include "BLI_string_ref.hh"
@@ -13,6 +15,7 @@
 #include "BKE_context.h"
 #include "BKE_customdata.h"
 #include "BKE_material.h"
+#include "BKE_paint.h"
 
 #include "NOD_shader.h"
 
@@ -22,12 +25,45 @@
 #include "RNA_define.h"
 
 namespace blender::ed::sculpt_paint::canvas {
-struct CanvasDef {
-  Material *ma;
+
+/**
+ * Encode the given material slot and resource index into a single int32_t.
+ *
+ * Result is used in rna enums.
+ */
+int32_t encode(uint16_t material_slot, uint16_t resource_index)
+{
+  int encoded = material_slot;
+  encoded <<= 16;
+  encoded |= resource_index;
+  return encoded;
+}
+
+/**
+ * Decode the given encoded value into a material slot.
+ */
+uint16_t decode_material_slot(int32_t encoded_value)
+{
+  return encoded_value >> 16;
+}
+
+/**
+ * Decide the given encoded value into a resource index.
+ */
+uint16_t decode_resource_index(int32_t encoded_value)
+{
+  return encoded_value & 65535;
+}
+
+struct MaterialCanvas {
+  uint16_t material_slot;
+  uint16_t resource_index;
+
   bNode *node;
   EnumPropertyItem rna_enum_item;
 
-  CanvasDef(Material *ma, bNode *node) : ma(ma), node(node)
+  MaterialCanvas(uint16_t material_slot, uint16_t resource_index, bNode *node)
+      : material_slot(material_slot), resource_index(resource_index), node(node)
   {
     init_rna_enum_item();
   }
@@ -54,8 +90,8 @@ struct CanvasDef {
   void init_rna_enum_item_image(Image *image)
   {
     BLI_assert(image != nullptr);
-    rna_enum_item.value = 0;
-    rna_enum_item.identifier = "IMAGE1";
+    rna_enum_item.value = encode(material_slot, resource_index);
+    rna_enum_item.identifier = image->id.name + 2;
     rna_enum_item.icon = ICON_IMAGE;
     rna_enum_item.name = image->id.name + 2;
     rna_enum_item.description = image->id.name + 2;
@@ -63,14 +99,33 @@ struct CanvasDef {
 
   void init_rna_enum_item_color_attribute(const NodeShaderAttribute *attribute)
   {
-    rna_enum_item.value = 0;
-    rna_enum_item.identifier = "COLOR_1";
+    rna_enum_item.value = encode(material_slot, resource_index);
+    rna_enum_item.identifier = attribute->name;
     rna_enum_item.icon = ICON_COLOR;
     rna_enum_item.name = attribute->name;
     rna_enum_item.description = attribute->name;
   }
 
  public:
+  void activate(Object *ob)
+  {
+    switch (node->type) {
+      case SH_NODE_TEX_IMAGE:
+        break;
+
+      case SH_NODE_ATTRIBUTE: {
+        NodeShaderAttribute *attribute = static_cast<NodeShaderAttribute *>(node->storage);
+
+        Mesh *mesh = (Mesh *)ob->data;
+        int layer = CustomData_get_named_layer_index(&mesh->vdata, CD_PROP_COLOR, attribute->name);
+        if (layer != -1) {
+          CustomData_set_layer_active_index(&mesh->vdata, CD_PROP_COLOR, layer);
+        }
+        break;
+      }
+    }
+  }
+
   static bool supports(const Object *ob, bNode *node)
   {
     switch (node->type) {
@@ -96,7 +151,7 @@ struct CanvasDef {
     }
   }
 
-  bool operator<(const CanvasDef &rhs) const
+  bool operator<(const MaterialCanvas &rhs) const
   {
     if (node->type != rhs.node->type) {
       return node->type == SH_NODE_TEX_IMAGE;
@@ -105,28 +160,57 @@ struct CanvasDef {
   }
 };
 
+struct MaterialCanvases {
+  Vector<MaterialCanvas> items;
+
+  const std::optional<MaterialCanvas> find(uint16_t resource_index) const
+  {
+    for (const MaterialCanvas &item : items) {
+      if (item.resource_index == resource_index) {
+        return item;
+      }
+    }
+    return std::nullopt;
+  }
+
+  std::optional<MaterialCanvas> active()
+  {
+    for (const MaterialCanvas &item : items) {
+      if ((item.node->flag & NODE_ACTIVE) != 0) {
+        return item;
+      }
+    }
+    return std::nullopt;
+  }
+};
+
 struct MaterialWrapper {
+  /** Index of the material slot. */
+  uint16_t material_slot;
+  /** Material inside the material slot. */
   Material *ma;
 
-  MaterialWrapper(Material *ma) : ma(ma)
+  MaterialWrapper(uint16_t material_slot, Material *ma) : material_slot(material_slot), ma(ma)
   {
   }
 
-  Vector<CanvasDef> canvases(const Object *ob)
+  MaterialCanvases canvases(const Object *ob) const
   {
-    Vector<CanvasDef> result;
+    MaterialCanvases result;
     if (!ma->use_nodes) {
       return result;
     }
 
     BLI_assert(ma->nodetree != nullptr);
+    uint16_t resource_index = 0;
     LISTBASE_FOREACH (bNode *, node, &ma->nodetree->nodes) {
-      if (!CanvasDef::supports(ob, node)) {
+      if (!MaterialCanvas::supports(ob, node)) {
         continue;
       }
-      result.append(CanvasDef(ma, node));
+      result.items.append(MaterialCanvas(material_slot, resource_index, node));
+      resource_index += 1;
     }
-    std::sort(result.begin(), result.end());
+    std::sort(result.items.begin(), result.items.end());
 
     return result;
   }
@@ -141,6 +225,24 @@ struct MaterialWrapper {
     item.description = ma->id.name + 2;
     RNA_enum_item_add(r_items, r_totitem, &item);
   }
+
+  /** Activate the material slot on the given object. */
+  void activate(Object *ob)
+  {
+    ob->actcol = material_slot + 1;
+  }
+
+  /** Activate a resource of this material. */
+  void activate(Object *ob, uint16_t resource_index)
+  {
+    MaterialCanvases resources = canvases(ob);
+    std::optional<MaterialCanvas> resource = resources.find(resource_index);
+    if (!resource.has_value()) {
+      return;
+    }
+    nodeSetActive(ma->nodetree, resource->node);
+    resource->activate(ob);
+  }
 };
 
 static Vector<MaterialWrapper> list_materials(Object *ob)
@@ -157,12 +259,37 @@ static Vector<MaterialWrapper> list_materials(Object *ob)
     if (ma == nullptr) {
       continue;
     }
-    result.append(ma);
+    result.append(MaterialWrapper(a, ma));
   }
 
   return result;
 }
 
+static std::optional<MaterialWrapper> get_material_in_slot(Object *ob, uint16_t material_slot)
+{
+  uint16_t *tot_colp = (uint16_t *)BKE_object_material_len_p(ob);
+  struct Material ***matarar = BKE_object_material_array_p(ob);
+  if (tot_colp == nullptr || matarar == nullptr) {
+    return std::nullopt;
+  }
+  if (material_slot >= *tot_colp) {
+    return std::nullopt;
+  }
+
+  Material *mat = (*matarar)[material_slot];
+  if (mat == nullptr) {
+    return std::nullopt;
+  }
+
+  return MaterialWrapper(material_slot, mat);
+}
+
+static std::optional<MaterialWrapper> get_active_material(Object *ob)
+{
+  uint16_t material_slot = (uint16_t)ob->actcol - 1;
+  return get_material_in_slot(ob, material_slot);
+}
+
 }  // namespace blender::ed::sculpt_paint::canvas
 
 extern "C" {
@@ -170,33 +297,49 @@ extern "C" {
 using namespace blender;
 using namespace blender::ed::sculpt_paint::canvas;
 
-int ED_paint_canvas_material_get(const struct bContext *C,
-                                 const struct PaintModeSettings *settings)
+int ED_paint_canvas_material_get(Object *ob)
 {
-  return 0;
+  std::optional<MaterialWrapper> material = get_active_material(ob);
+  if (!material.has_value()) {
+    return 0;
+  }
+  std::optional<MaterialCanvas> resource = material->canvases(ob).active();
+  if (!resource.has_value()) {
+    return 0;
+  }
+  return resource->rna_enum_item.value;
 }
 
-void ED_paint_canvas_material_set(struct bContext *C,
-                                  const struct PaintModeSettings *settings,
-                                  int new_value)
+void ED_paint_canvas_material_set(Object *ob, int new_value)
 {
+  const uint16_t resource_index

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list