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:
authorJoseph Eagar <joeedh@gmail.com>2021-09-18 22:10:14 +0300
committerJoseph Eagar <joeedh@gmail.com>2021-09-18 22:10:14 +0300
commit1ca57bc5f42bf92f672bf28a8a22d4d49bf5aee8 (patch)
tree3d5eecdb7c0c7933ef0af42ef6fab852273874a8
parent7749b89d74cf05264114425f6e7f4d4c4631d0ab (diff)
Sculpt: flushed out brush channel RNA and made basic UI
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py79
-rw-r--r--source/blender/blenkernel/BKE_brush_engine.h13
-rw-r--r--source/blender/blenkernel/intern/brush_engine.c138
-rw-r--r--source/blender/blenkernel/intern/scene.c16
-rw-r--r--source/blender/editors/interface/interface_handlers.c2
-rw-r--r--source/blender/makesdna/DNA_sculpt_brush_types.h15
-rw-r--r--source/blender/makesrna/intern/rna_brush_engine.c124
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c6
8 files changed, 371 insertions, 22 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 3c5926e5972..c8d7817e5a7 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -19,7 +19,6 @@
# <pep8 compliant>
from bpy.types import Menu
-
class UnifiedPaintPanel:
# subclass must set
# bl_space_type = 'IMAGE_EDITOR'
@@ -98,6 +97,68 @@ class UnifiedPaintPanel:
return None
@staticmethod
+ def channel_unified(layout, context, brush, prop_name, icon='NONE', pressure=True, text=None, slider=False, header=False):
+ """ Generalized way of adding brush options to the UI,
+ along with their pen pressure setting and global toggle, if they exist. """
+ ch = brush.channels.channels[prop_name]
+ finalch = ch
+
+ l1 = layout
+
+ if ch.ui_expanded:
+ layout = layout.box().column() #.column() is a bit more compact
+
+ row = layout.row(align=True)
+
+ if text is None:
+ s = prop_name.lower().replace("_", " ").split(" ");
+ text = ''
+ for k in s:
+ text += k[0].upper() + k[1:] + " "
+ text = text.strip()
+
+ if ch.inherit:
+ sd = context.tool_settings.sculpt
+ #ensure channel exists in tool settings channel set
+ sd.channels.ensure(ch)
+
+ finalch = sd.channels.channels[prop_name]
+
+ row.prop(finalch, "value", icon=icon, text=text, slider=slider)
+
+ if pressure:
+ row.prop(finalch.mappings["PRESSURE"], "enabled", text="", icon="STYLUS_PRESSURE")
+ #if pressure_name:
+ # row.prop(brush, pressure_name, text="")
+
+ #if unified_name and not header:
+ # # NOTE: We don't draw UnifiedPaintSettings in the header to reduce clutter. D5928#136281
+ # row.prop(ups, unified_name, text="", icon='BRUSHES_ALL')
+ if not header:
+ row.prop(ch, "inherit", text="", icon='BRUSHES_ALL')
+ row.prop(ch, "ui_expanded", text="", icon="TRIA_DOWN" if ch.ui_expanded else "TRIA_RIGHT")
+
+ if ch.ui_expanded:
+ for mp in finalch.mappings:
+ row2 = layout.row()
+ name = mp.type.lower()
+
+ if len(name) > 0:
+ name = name[0].upper() + name[1:]
+ else:
+ name = "name error"
+
+ row2.label(text=name)
+ row2.prop(mp, "enabled", text="", icon="STYLUS_PRESSURE")
+ row2.prop(mp, "ui_expanded", text="", icon="TRIA_DOWN" if mp.ui_expanded else "TRIA_RIGHT")
+
+ if mp.ui_expanded:
+ layout.template_curve_mapping(mp, "curve", brush=True)
+ #row2.prop(mp, "curve")
+
+ return row
+
+ @staticmethod
def prop_unified(
layout,
context,
@@ -972,11 +1033,16 @@ def brush_shared_settings(layout, context, brush, popover=False):
layout.row().prop(size_owner, "use_locked_size", expand=True)
layout.separator()
- #if strength and mode == "SCULPT":
- # layout.prop(brush.channels.channels["STRENGTH"], "value", text="Strength")
- # pass
- #elif strength:
- if strength:
+ if 0 and strength:
+ UnifiedPaintPanel.channel_unified(
+ layout,
+ context,
+ brush,
+ "STRENGTH",
+ slider=True
+ )
+ layout.separator()
+ elif strength:
pressure_name = "use_pressure_strength" if strength_pressure else None
UnifiedPaintPanel.prop_unified(
layout,
@@ -988,7 +1054,6 @@ def brush_shared_settings(layout, context, brush, popover=False):
slider=True,
)
layout.separator()
-
if direction:
layout.row().prop(brush, "direction", expand=True)
diff --git a/source/blender/blenkernel/BKE_brush_engine.h b/source/blender/blenkernel/BKE_brush_engine.h
index 5695cae3649..6b038f6d063 100644
--- a/source/blender/blenkernel/BKE_brush_engine.h
+++ b/source/blender/blenkernel/BKE_brush_engine.h
@@ -92,13 +92,19 @@ typedef struct BrushCommandList {
} BrushCommandList;
void BKE_brush_channel_free(BrushChannel *ch);
-void BKE_brush_channel_copy(BrushChannel *dst, BrushChannel *src);
+void BKE_brush_channel_copy_data(BrushChannel *dst, BrushChannel *src);
void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def);
-BrushChannelSet *BKE_brush_channelset_create();
+BrushChannelSet *BKE_brush_channelset_create();
+BrushChannelSet *BKE_brush_channelset_copy(BrushChannelSet *src);
void BKE_brush_channelset_free(BrushChannelSet *chset);
+
+// makes a copy of ch
void BKE_brush_channelset_add(BrushChannelSet *chset, BrushChannel *ch);
+// checks is a channel with existing->idname exists; if not a copy of existing is made and inserted
+void BKE_brush_channelset_ensure_existing(BrushChannelSet *chset, BrushChannel *existing);
+
BrushChannel *BKE_brush_channelset_lookup(BrushChannelSet *chset, const char *idname);
bool BKE_brush_channelset_has(BrushChannelSet *chset, const char *idname);
@@ -123,6 +129,9 @@ BrushCommand *BKE_brush_command_init(BrushCommand *command, int tool);
void BKE_builtin_commandlist_create(BrushChannelSet *chset, BrushCommandList *cl, int tool);
void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *cset);
void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *cset);
+void BKE_brush_mapping_copy_data(BrushMapping *dst, BrushMapping *src);
+const char *BKE_brush_mapping_type_to_str(BrushMappingType mapping);
+const char *BKE_brush_mapping_type_to_typename(BrushMappingType mapping);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/brush_engine.c b/source/blender/blenkernel/intern/brush_engine.c
index 6c4e879be3f..f35bd0d56dc 100644
--- a/source/blender/blenkernel/intern/brush_engine.c
+++ b/source/blender/blenkernel/intern/brush_engine.c
@@ -8,6 +8,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
+#include "BLI_rect.h"
#include "DNA_brush_enums.h"
#include "DNA_brush_types.h"
@@ -31,6 +32,31 @@
#define ICON_NONE -1
+static bool check_corrupted_curve(BrushMapping *dst)
+{
+
+ const float clip_size_x = BLI_rctf_size_x(&dst->curve.curr);
+ const float clip_size_y = BLI_rctf_size_y(&dst->curve.curr);
+
+ // fix corrupted curve
+ if (clip_size_x == 0.0f || clip_size_y == 0.0f) {
+ for (int i = 0; i < 4; i++) {
+ BKE_curvemapping_free_data(&dst->curve);
+ BKE_curvemapping_set_defaults(&dst->curve, 1, 0.0, 0.0, 1.0, 1.0);
+
+ BKE_curvemap_reset(&dst->curve.cm[i],
+ &(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
+ CURVE_PRESET_LINE,
+ dst->flag & BRUSH_MAPPING_INVERT);
+ BKE_curvemapping_init(&dst->curve);
+ }
+
+ return false;
+ }
+
+ return true;
+}
+
/*
Brush command lists.
@@ -50,6 +76,7 @@ BrushChannelType brush_builtin_channels[] = {
.min = 0.001f,
.type = BRUSH_CHANNEL_FLOAT,
.max = 2048.0f,
+ .fvalue = 50.0f,
.soft_min = 0.1f,
.soft_max = 1024.0f,
.mappings = {
@@ -62,6 +89,7 @@ BrushChannelType brush_builtin_channels[] = {
.min = -1.0f,
.type = BRUSH_CHANNEL_FLOAT,
.max = 4.0f,
+ .fvalue = 0.5f,
.soft_min = 0.0f,
.soft_max = 1.0f,
.mappings = {
@@ -74,6 +102,7 @@ BrushChannelType brush_builtin_channels[] = {
.min = 0.001f,
.type = BRUSH_CHANNEL_FLOAT,
.max = 4.0f,
+ .fvalue = 0.1f,
.soft_min = 0.005f,
.soft_max = 2.0f,
.mappings = {
@@ -110,6 +139,7 @@ BrushChannelType brush_builtin_channels[] = {
.type = BRUSH_CHANNEL_FLOAT,
.min = 0.0001f,
.max = 25.0f,
+ .fvalue = 1.0f,
.soft_min = 0.1f,
.soft_max = 4.0f,
.mappings = {
@@ -122,6 +152,7 @@ BrushChannelType brush_builtin_channels[] = {
.type = BRUSH_CHANNEL_FLOAT,
.min = 0.0001f,
.max = 25.0f,
+ .fvalue = 1.0f,
.soft_min = 0.1f,
.soft_max = 4.0f,
.mappings = {
@@ -134,6 +165,7 @@ BrushChannelType brush_builtin_channels[] = {
.type = BRUSH_CHANNEL_FLOAT,
.min = 0.0001f,
.max = 1.0f,
+ .fvalue = 1.0f,
.soft_min = 0.1f,
.soft_max = 1.0f,
.mappings = {
@@ -215,12 +247,13 @@ void BKE_brush_channel_free(BrushChannel *ch)
}
}
-ATTR_NO_OPT void BKE_brush_channel_copy(BrushChannel *dst, BrushChannel *src)
+ATTR_NO_OPT void BKE_brush_channel_copy_data(BrushChannel *dst, BrushChannel *src)
{
*dst = *src;
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
- BKE_curvemapping_copy_data(&dst->mappings[i].curve, &src->mappings[i].curve);
+ BKE_brush_mapping_copy_data(dst->mappings + i, src->mappings + i);
+ dst->mappings[i].type = i;
}
}
@@ -241,6 +274,8 @@ ATTR_NO_OPT void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
BrushMapping *map = ch->mappings + i;
CurveMapping *curve = &map->curve;
+ map->type = i;
+
memset(curve, 0, sizeof(*curve));
float min, max;
@@ -262,9 +297,11 @@ ATTR_NO_OPT void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
int slope = CURVEMAP_SLOPE_POSITIVE;
+ BKE_curvemapping_set_defaults(curve, 1, 0, min, 1, max);
+
for (int i = 0; i < 4; i++) {
BKE_curvemap_reset(&curve->cm[i],
- &(struct rctf){.xmax = 0, .ymax = min, .xmax = 1, .ymax = max},
+ &(struct rctf){.xmin = 0, .ymin = min, .xmax = 1, .ymax = max},
mdef->curve,
slope);
}
@@ -308,7 +345,7 @@ void BKE_brush_channelset_add(BrushChannelSet *chset, BrushChannel *ch)
chset->channels = MEM_recallocN(chset->channels, sizeof(BrushChannel) * chset->totchannel);
}
- memcpy(chset->channels + chset->totchannel - 1, ch, sizeof(BrushChannel));
+ BKE_brush_channel_copy_data(chset->channels + chset->totchannel - 1, ch);
}
ATTR_NO_OPT BrushChannel *BKE_brush_channelset_lookup(BrushChannelSet *chset, const char *idname)
@@ -391,6 +428,14 @@ bool BKE_brush_channelset_ensure_builtin(BrushChannelSet *chset, const char *idn
return false;
}
+void BKE_brush_channelset_ensure_existing(BrushChannelSet *chset, BrushChannel *existing)
+{
+ if (BKE_brush_channelset_has(chset, existing->idname)) {
+ return;
+ }
+
+ BKE_brush_channelset_add(chset, existing);
+}
#define ADDCH(name) BKE_brush_channelset_ensure_builtin(chset, name)
#define GETCH(name) BKE_brush_channelset_lookup(chset, name)
@@ -411,7 +456,7 @@ void BKE_brush_channelset_merge(BrushChannelSet *dst,
}
BrushChannel ch2;
- BKE_brush_channel_copy(&ch2, ch);
+ BKE_brush_channel_copy_data(&ch2, ch);
BKE_brush_channelset_add(chset, &ch2);
}
}
@@ -425,7 +470,7 @@ void BKE_brush_channelset_merge(BrushChannelSet *dst,
if (ch->flag & BRUSH_CHANNEL_INHERIT) {
BKE_brush_channel_free(mch);
- BKE_brush_channel_copy(mch, pch);
+ BKE_brush_channel_copy_data(mch, pch);
continue;
}
@@ -435,6 +480,28 @@ void BKE_brush_channelset_merge(BrushChannelSet *dst,
}
}
+BrushChannelSet *BKE_brush_channelset_copy(BrushChannelSet *src)
+{
+ BrushChannelSet *chset = BKE_brush_channelset_create();
+
+ *chset = *src;
+
+ if (!chset->totchannel) {
+ return chset;
+ }
+
+ chset->channels = MEM_calloc_arrayN(
+ src->totchannel, sizeof(BrushChannel), "chset->channels copied");
+
+ for (int i = 0; i < chset->totchannel; i++) {
+ BrushChannel *ch = chset->channels + i;
+
+ BKE_brush_channel_copy_data(ch, src->channels + i);
+ }
+
+ return chset;
+}
+
void BKE_brush_resolve_channels(Brush *brush, Sculpt *sd)
{
if (brush->channels_final) {
@@ -655,6 +722,12 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *cset)
for (int j = 0; j < BRUSH_MAPPING_MAX; j++) {
BKE_curvemapping_blend_read(reader, &ch->mappings[j].curve);
+ BKE_curvemapping_init(&ch->mappings[j].curve);
+
+ check_corrupted_curve(ch->mappings + j);
+
+ // paranoia check to make sure BrushMapping.type is correct
+ ch->mappings[j].type = j;
}
ch->def = BKE_brush_builtin_channel_def_find(ch->idname);
@@ -680,6 +753,59 @@ void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *cset)
}
}
+const char *BKE_brush_mapping_type_to_str(BrushMappingType mapping)
+{
+ switch (mapping) {
+ case BRUSH_MAPPING_PRESSURE:
+ return "Pressure";
+ case BRUSH_MAPPING_ANGLE:
+ return "Angle";
+ case BRUSH_MAPPING_SPEED:
+ return "Speed";
+ case BRUSH_MAPPING_XTILT:
+ return "X Tilt";
+ case BRUSH_MAPPING_YTILT:
+ return "Y Tilt";
+ case BRUSH_MAPPING_MAX:
+ return "Error";
+ }
+
+ return "Error";
+}
+
+const char *BKE_brush_mapping_type_to_typename(BrushMappingType mapping)
+{
+ switch (mapping) {
+ case BRUSH_MAPPING_PRESSURE:
+ return "PRESSURE";
+ case BRUSH_MAPPING_ANGLE:
+ return "ANGLE";
+ case BRUSH_MAPPING_SPEED:
+ return "SPEED";
+ case BRUSH_MAPPING_XTILT:
+ return "XTILT";
+ case BRUSH_MAPPING_YTILT:
+ return "YTILT";
+ case BRUSH_MAPPING_MAX:
+ return "Error";
+ }
+
+ return "Error";
+}
+
+void BKE_brush_mapping_copy_data(BrushMapping *dst, BrushMapping *src)
+{
+ // do not copy .type
+ int type = dst->type;
+ *dst = *src;
+ dst->type = type;
+
+ BKE_curvemapping_copy_data(&dst->curve, &src->curve);
+ BKE_curvemapping_init(&dst->curve);
+
+ check_corrupted_curve(dst);
+}
+
/* clang-format on */
/* idea for building built-in preset node graphs:
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 74fc5e6de7a..6824afadb3e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1060,6 +1060,9 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &sce->toolsettings->sculpt->channels);
BKE_brush_channelset_read(reader, sce->toolsettings->sculpt->channels);
}
+ else {
+ sce->toolsettings->sculpt->channels = BKE_brush_channelset_create();
+ }
/* relink grease pencil interpolation curves */
BLO_read_data_address(reader, &sce->toolsettings->gp_interpolate.custom_ipo);
@@ -1608,6 +1611,14 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
}
if (ts->sculpt) {
ts->sculpt = MEM_dupallocN(ts->sculpt);
+
+ if (ts->sculpt->channels) {
+ ts->sculpt->channels = BKE_brush_channelset_copy(ts->sculpt->channels);
+ }
+ else {
+ ts->sculpt->channels = BKE_brush_channelset_create();
+ }
+
BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag);
}
if (ts->uvsculpt) {
@@ -1663,6 +1674,11 @@ void BKE_toolsettings_free(ToolSettings *toolsettings)
}
if (toolsettings->sculpt) {
BKE_paint_free(&toolsettings->sculpt->paint);
+
+ if (toolsettings->sculpt->channels) {
+ BKE_brush_channelset_free(toolsettings->sculpt->channels);
+ }
+
MEM_freeN(toolsettings->sculpt);
}
if (toolsettings->uvsculpt) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index d4eff9f1151..5cfe8740eb0 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -7193,7 +7193,7 @@ static bool ui_numedit_but_CURVE(uiBlock *block,
return changed;
}
-static int ui_do_but_CURVE(
+ATTR_NO_OPT static int ui_do_but_CURVE(
bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
bool changed = false;
diff --git a/source/blender/makesdna/DNA_sculpt_brush_types.h b/source/blender/makesdna/DNA_sculpt_brush_types.h
index eba4c89c5b5..b8d70567520 100644
--- a/source/blender/makesdna/DNA_sculpt_brush_types.h
+++ b/source/blender/makesdna/DNA_sculpt_brush_types.h
@@ -30,7 +30,7 @@ typedef struct BrushMapping {
float factor;
short blendmode;
short input_channel;
- int flag, _pad[1];
+ int flag, type;
} BrushMapping;
typedef struct BrushChannel {
@@ -52,17 +52,21 @@ typedef struct BrushChannelSet {
} BrushChannelSet;
// mapping flags
-enum { BRUSH_MAPPING_ENABLED = 1 << 0, BRUSH_MAPPING_INVERT = 1 << 1 };
+enum {
+ BRUSH_MAPPING_ENABLED = 1 << 0,
+ BRUSH_MAPPING_INVERT = 1 << 1,
+ BRUSH_MAPPING_UI_EXPANDED = 1 << 2
+};
// mapping types
-enum {
+typedef enum {
BRUSH_MAPPING_PRESSURE = 0,
BRUSH_MAPPING_XTILT = 1,
BRUSH_MAPPING_YTILT = 2,
BRUSH_MAPPING_ANGLE = 3,
BRUSH_MAPPING_SPEED = 4,
BRUSH_MAPPING_MAX = 5 // see BrushChannel.mappings
-};
+} BrushMappingType;
static_assert(offsetof(BrushChannel, type) - offsetof(BrushChannel, mappings) ==
sizeof(BrushMapping) * BRUSH_MAPPING_MAX,
@@ -72,7 +76,8 @@ static_assert(offsetof(BrushChannel, type) - offsetof(BrushChannel, mappings) ==
enum {
BRUSH_CHANNEL_INHERIT = 1 << 0,
BRUSH_CHANNEL_INHERIT_IF_UNSET = 1 << 1,
- BRUSH_CHANNEL_NO_MAPPINGS = 1 << 2
+ BRUSH_CHANNEL_NO_MAPPINGS = 1 << 2,
+ BRUSH_CHANNEL_UI_EXPANDED = 1 << 3
};
// BrushChannelType->type
diff --git a/source/blender/makesrna/intern/rna_brush_engine.c b/source/blender/makesrna/intern/rna_brush_engine.c
index e05c0bd4690..6cabd177780 100644
--- a/source/blender/makesrna/intern/rna_brush_engine.c
+++ b/source/blender/makesrna/intern/rna_brush_engine.c
@@ -29,6 +29,7 @@
#include "DNA_workspace_types.h"
#include "BLI_math.h"
+#include "BLI_utildefines.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -38,6 +39,7 @@
#include "IMB_imbuf.h"
#include "BKE_brush_engine.h"
+#include "BKE_colortools.h"
#include "DNA_sculpt_brush_types.h"
#include "WM_types.h"
@@ -61,7 +63,7 @@ int rna_BrushChannelSet_channels_assignint(struct PointerRNA *ptr,
BrushChannel *ch = chset->channels + key;
BrushChannel *src = assign_ptr->data;
- BKE_brush_channel_copy(ch, src);
+ BKE_brush_channel_copy_data(ch, src);
return 1;
}
@@ -97,8 +99,102 @@ void rna_BrushChannel_value_range(
*soft_max = 1.0f;
}
}
+
+PointerRNA rna_BrushMapping_curve_get(PointerRNA *ptr)
+{
+ BrushMapping *mapping = (BrushMapping *)ptr->data;
+
+ return rna_pointer_inherit_refine(ptr, &RNA_CurveMapping, &mapping->curve);
+}
+
+int rna_BrushChannel_mappings_begin(CollectionPropertyIterator *iter, struct PointerRNA *ptr)
+{
+ BrushChannel *ch = ptr->data;
+
+ rna_iterator_array_begin(
+ iter, ch->mappings, sizeof(BrushMapping), BRUSH_MAPPING_MAX, false, NULL);
+
+ return 1;
+}
+
+int rna_BrushChannel_mappings_assignint(struct PointerRNA *ptr,
+ int key,
+ const struct PointerRNA *assign_ptr)
+{
+ BrushChannel *ch = ptr->data;
+ BrushMapping *dst = ch->mappings + key;
+ BrushMapping *src = assign_ptr->data;
+
+ BKE_brush_mapping_copy_data(dst, src);
+
+ return 1;
+}
+
+int rna_BrushChannel_mappings_lookupstring(PointerRNA *rna, const char *key, PointerRNA *r_ptr)
+{
+ BrushChannel *ch = (BrushChannel *)rna->data;
+
+ for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
+ if (STREQ(key, BKE_brush_mapping_type_to_typename(i))) {
+ if (r_ptr) {
+ *r_ptr = rna_pointer_inherit_refine(rna, &RNA_BrushMapping, ch->mappings + i);
+ }
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int rna_BrushChannel_mappings_length(PointerRNA *ptr)
+{
+ return BRUSH_MAPPING_MAX;
+}
+
#endif
+static EnumPropertyItem mapping_type_items[] = {
+ {BRUSH_MAPPING_PRESSURE, "PRESSURE", ICON_NONE, "Pressure"},
+ {BRUSH_MAPPING_XTILT, "XTILT", ICON_NONE, "X Tilt"},
+ {BRUSH_MAPPING_YTILT, "YTILT", ICON_NONE, "Y Tilt"},
+ {BRUSH_MAPPING_ANGLE, "ANGLE", ICON_NONE, "Angle"},
+ {BRUSH_MAPPING_SPEED, "SPEED", ICON_NONE, "Speed"},
+ {-1, NULL, -1, -1},
+};
+
+void RNA_def_brush_mapping(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "BrushMapping", NULL);
+ RNA_def_struct_sdna(srna, "BrushMapping");
+ RNA_def_struct_ui_text(srna, "Brush Mapping", "Brush Mapping");
+
+ prop = RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "CurveMapping");
+ RNA_def_property_ui_text(prop, "Curve Sensitivity", "Curve used for the sensitivity");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_pointer_funcs(prop, "rna_BrushMapping_curve_get", NULL, NULL, NULL);
+
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, "BrushMapping", "type");
+ RNA_def_property_enum_items(prop, mapping_type_items);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE | PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Type", "Channel Type");
+
+ prop = RNA_def_property(srna, "enabled", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, "BrushMapping", "flag", BRUSH_MAPPING_ENABLED);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(prop, "Enabled", "Input Mapping Is Enabled");
+
+ prop = RNA_def_property(srna, "ui_expanded", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, "BrushMapping", "flag", BRUSH_MAPPING_UI_EXPANDED);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(prop, "Expanded", "View advanced properties");
+}
+
extern BrushChannelType *brush_builtin_channels;
extern const int builtin_channel_len;
@@ -148,21 +244,46 @@ void RNA_def_brush_channel(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Inherit", "Inherit from scene defaults");
+ prop = RNA_def_property(srna, "ui_expanded", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, "BrushChannel", "flag", BRUSH_CHANNEL_UI_EXPANDED);
+ RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
+ RNA_def_property_ui_text(prop, "Expanded", "View advanced properties");
+
prop = RNA_def_property(srna, "inherit_if_unset", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, "BrushChannel", "flag", BRUSH_CHANNEL_INHERIT_IF_UNSET);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Inherit If Unset", "Combine with default settings");
+
+ prop = RNA_def_property(srna, "mappings", PROP_COLLECTION, PROP_NONE);
+ // RNA_def_property_collection_sdna(prop, "BrushChannel", "mappings", NULL);
+ RNA_def_property_collection_funcs(prop,
+ "rna_BrushChannel_mappings_begin",
+ "rna_iterator_array_next",
+ "rna_iterator_array_end",
+ "rna_iterator_array_get",
+ "rna_BrushChannel_mappings_length",
+ NULL,
+ "rna_BrushChannel_mappings_lookupstring",
+ "rna_BrushChannel_mappings_assignint");
+ RNA_def_property_struct_type(prop, "BrushMapping");
}
void RNA_def_brush_channelset(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
+ PropertyRNA *parm;
srna = RNA_def_struct(brna, "BrushChannelSet", NULL);
RNA_def_struct_sdna(srna, "BrushChannelSet");
RNA_def_struct_ui_text(srna, "Channel Set", "Brush Channel Collection");
+ func = RNA_def_function(srna, "ensure", "BKE_brush_channelset_ensure_existing");
+ parm = RNA_def_pointer(
+ func, "channel", "BrushChannel", "", "Ensure a copy of channel exists in this channel set");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
prop = RNA_def_property(srna, "channels", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "channels", "totchannel");
RNA_def_property_collection_funcs(prop,
@@ -181,6 +302,7 @@ void RNA_def_brush_channelset(BlenderRNA *brna)
void RNA_def_brush_engine(BlenderRNA *brna)
{
+ RNA_def_brush_mapping(brna);
RNA_def_brush_channel(brna);
RNA_def_brush_channelset(brna);
}
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 3ad578b0f22..3aca5ed83f6 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -830,6 +830,12 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_Sculpt_path");
RNA_def_struct_ui_text(srna, "Sculpt", "");
+ prop = RNA_def_property(srna, "channels", PROP_POINTER, 0);
+ RNA_def_property_pointer_sdna(prop, NULL, "channels");
+ RNA_def_property_struct_type(prop, "BrushChannelSet");
+ RNA_def_property_ui_text(prop, "Channels", "");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
+
prop = RNA_def_property(srna, "radial_symmetry", PROP_INT, PROP_XYZ);
RNA_def_property_int_sdna(prop, NULL, "radial_symm");
RNA_def_property_int_default(prop, 1);