[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