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:
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py318
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py1
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py78
-rw-r--r--source/blender/blenkernel/BKE_brush_channel.h17
-rw-r--r--source/blender/blenkernel/intern/brush.cc28
-rw-r--r--source/blender/blenkernel/intern/brush_channel.cc269
-rw-r--r--source/blender/blenkernel/intern/brush_channel_define.h218
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c31
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_brush_channels.c20
-rw-r--r--source/blender/makesrna/intern/rna_scene.c4
11 files changed, 897 insertions, 89 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 9b36f65ded5..da0058db008 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -1,6 +1,250 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from bpy.types import Menu, Panel
+builtin_channel_categories = [
+ "Basic", "Paint", "Smooth", "Cloth", "Automasking"
+]
+
+class DynamicBrushCategoryPanel(Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'UI'
+ bl_category = "Tool"
+
+ @classmethod
+ def poll(self, context):
+ ok = context.mode == "SCULPT" and context.tool_settings.sculpt and context.tool_settings.sculpt.brush
+ ok = ok and len(self.get_channels(context)) > 0
+
+ return ok
+
+ @classmethod
+ def get_channels(self, context):
+ brush = context.tool_settings.sculpt.brush
+
+ idname = self.get_category(self)
+
+ #for ch in brush.channels:
+ # print(ch.idname, ch.show_in_workspace)
+
+ channels = list(filter(lambda ch: ch.show_in_workspace and ch.category == idname, brush.channels))
+ channels.sort(key=lambda ch: ch.ui_order)
+
+ return channels
+
+ def draw(self, context):
+ layout = self.layout
+ brush = context.tool_settings.sculpt.brush
+
+ idname = self.get_category()
+ opt = self.get_options()
+
+ layout.use_property_split = True
+
+ channels = self.get_channels(context)
+ group = DynamicPaintPanelGen.getGroup(self)
+
+ for ch in channels:
+ name = ch.name
+
+ # Handle size/unprojected_radius hack.
+ if ch.idname == "size" and brush.use_locked_size == "SCENE":
+ continue
+ if ch.idname == "unprojected_radius":
+ if brush.use_locked_size != "SCENE":
+ continue
+ name = "Radius"
+
+ inserts = group.getInserts(ch.idname) if group else []
+
+ ok = ch.show_in_workspace
+ ok = ok and ch.category == idname
+
+ if not ok:
+ continue
+
+ row = layout if len(inserts) == 0 else layout.row(align=True)
+
+ UnifiedPaintPanel.channel_unified(row,
+ context,
+ brush,
+ ch.idname,
+ slider=True,
+ ui_editing=opt["ui_editing"],
+ show_reorder=opt["show_reorder"],
+ show_mappings=opt["show_mappings"],
+ text=name)
+
+ for item in inserts:
+ if item.sameLine:
+ item.cb(row)
+
+ for item in inserts:
+ if not item.sameLine:
+ item.cb(layout)
+
+class InsertAfterItem:
+ def __init__(self, cb, sameLine):
+ self.cb = cb
+ self.sameLine = sameLine
+
+class DynamicPaintPanelGen:
+ class Group:
+ def __init__(self, idname, name, prefix, parent):
+ self.idname = idname
+ self.name = name
+ self.prefix = prefix
+ self.rnaclass = None
+ self.parent = parent
+ self.options = {}
+ self.insert_cbs = {}
+
+ def getInserts(self, key):
+ return self.insert_cbs[key] if key in self.insert_cbs else []
+
+ def insertEachAfter(self, insertdict):
+ #return
+ for key in insertdict.keys():
+ item = insertdict[key]
+
+ if isinstance(item, dict):
+ callback = item["callback"]
+ sameLine = item["sameLine"] if "sameLine" in item else False
+ else:
+ callback = item
+ sameLine = False
+
+ self.insertAfter(key, callback, sameLine)
+
+ def insertAfter(self, key, cb, sameLine=True):
+ """
+ example:
+ group.insertAfter("color", lambda layout: layout.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="", emboss=False))
+ """
+ if key not in self.insert_cbs:
+ self.insert_cbs[key] = []
+
+ self.insert_cbs[key].append(InsertAfterItem(cb, sameLine))
+
+ groups = {}
+
+ @staticmethod
+ def getGroup(panel):
+ idname = panel.bl_idname
+
+ return DynamicPaintPanelGen.groups[idname] if idname in DynamicPaintPanelGen.groups else None
+
+ @staticmethod
+ def ensureCategory(idname, name=None, prefix="VIEW3D_PT_brush_category_", parent=None, show_reorder=False, ui_editing=False, show_mappings=None):
+ if name is None:
+ name = idname
+
+ groupid = prefix + idname.lower()
+
+ if groupid in DynamicPaintPanelGen.groups:
+ return DynamicPaintPanelGen.groups[groupid]
+
+ group = DynamicPaintPanelGen.Group(idname, name, prefix, parent)
+ DynamicPaintPanelGen.groups[groupid] = group
+
+ group.options = {
+ "ui_editing": ui_editing,
+ "show_reorder": show_reorder,
+ "show_mappings" : show_mappings
+ }
+
+ def callback():
+ DynamicPaintPanelGen.createPanel(group)
+ pass
+
+ import bpy
+ bpy.app.timers.register(callback)
+
+ return group
+
+ @staticmethod
+ def get(idname, prefix):
+ return DynamicPaintPanelGen.groups[idname]
+
+ @staticmethod
+ def createPanel(group):
+ from bpy.utils import register_class, unregister_class
+
+ from bpy.types import Panel
+ global classes
+
+ name = group.prefix + group.idname.lower()
+ name1 = name
+ name2 = ""
+
+ for c in name:
+ n = ord(c)
+
+ ok = n >= ord("a") and n <= ord("z")
+ ok = ok or (n >= ord("A") and n <= ord("Z"))
+ ok = ok or (n >= ord("0") and n <= ord("9"))
+ ok = ok or c == "_"
+
+ if not ok:
+ c = "_"
+
+ name2 += c
+ name = name2
+
+ for cls in classes[:]:
+ if cls.bl_rna.identifier == name:
+ try:
+ unregister_class(cls)
+ except:
+ print("failed to unregister", name)
+
+ classes.remove(cls)
+
+ if group.parent:
+ parent = 'bl_parent_id = "%s"' % group.parent
+ else:
+ parent = ""
+
+ opt = repr(group.options)
+
+ code = """
+
+global classes
+
+class CLASSNAME (DynamicBrushCategoryPanel):
+ bl_label = "LABEL"
+ PARENT
+
+ def get_category(self):
+ return "IDNAME"
+
+ def get_options(self):
+ return OPT
+
+register_class(CLASSNAME)
+classes.append(CLASSNAME)
+
+""".strip().replace("CLASSNAME", name).replace("PARENT", parent).replace("LABEL", group.name).replace("OPT", opt)
+ code = code.replace("IDNAME", group.idname)
+
+ exec(code)
+
+#custom UI code that is inserted
+#for different brush channel properties
+insertAfters = {
+ "color" : {
+ "sameLine" : True,
+ "callback" : lambda layout: layout.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="", emboss=False)
+ }
+}
+
+#pre create category panels in correct order
+for cat in builtin_channel_categories:
+ DynamicPaintPanelGen.ensureCategory(cat, cat, parent="VIEW3D_PT_tools_brush_settings_channels", prefix="VIEW3D_PT_brush_category_",
+ ui_editing=False, show_reorder=True, show_mappings=True).insertEachAfter(insertAfters)
+ #DynamicPaintPanelGen.ensureCategory(cat, cat, prefix="VIEW3D_PT_brush_category_edit_",
+ # parent="VIEW3D_PT_tools_brush_settings_channels_preview").insertEachAfter(insertAfters)
+
+
def template_curve(layout, base, propname, full_path, use_negative_slope=None):
layout.template_curve_mapping(base, propname, brush=True, use_negative_slope=use_negative_slope)
@@ -23,6 +267,14 @@ class BRUSH_PT_channel_panel(Panel):
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
+ @classmethod
+ def poll(cls, context):
+ if not context.object:
+ return False
+
+ mode = context.object.mode
+ return mode in {"SCULPT", "VERTEX_PAINT", "WEIGHT_PAINT", "TEXTURE_PAINT"}
+
def draw(self, context):
layout = self.layout
layout.use_property_split = True
@@ -125,6 +377,28 @@ class UnifiedPaintPanel:
return None
@staticmethod
+ def get_channel(context, brush, prop_name, toolsettings_only=False, need_path=False):
+ ch = brush.channels[prop_name] if prop_name in brush.channels else None
+ unified_ch = context.tool_settings.unified_channels[prop_name]
+
+ path = None
+ inherit = False
+
+ if ch:
+ path = "sculpt.brush.channels[\"%s\"]" % prop_name
+ inherit = ch.inherit or (unified_ch.unified and not ch.disable_unified)
+
+ if not ch or inherit or toolsettings_only:
+ ch = context.tool_settings.unified_channels[prop_name]
+ path = "tool_settings.unified_channels[\"%s\"]" % prop_name
+
+ if need_path:
+ path = "tool_settings." + path
+ return (ch, path)
+ else:
+ return ch
+
+ @staticmethod
def paint_settings(context):
tool_settings = context.tool_settings
@@ -185,8 +459,7 @@ class UnifiedPaintPanel:
elif ui_editing is None:
ui_editing = True
- #XXX
- if 1: #not context.tool_settings.unified_paint_settings.brush_editor_mode:
+ if not context.tool_settings.brush_editor_mode:
ui_editing = False
show_reorder = False
@@ -1384,6 +1657,45 @@ def brush_shared_settings(layout, context, brush, popover=False):
if direction:
layout.row().prop(brush, "direction", expand=True)
+def get_ui_channels(channels, filterkeys=["show_in_workspace"]):
+ ret = []
+
+ for ch in channels:
+ ok = len(filterkeys) == 0
+ for key in filterkeys:
+ if getattr(ch, key):
+ ok = True
+ break
+ if ok:
+ ret.append(ch)
+
+ ret.sort(key=lambda x: x.ui_order)
+
+ return ret
+
+def brush_settings_channels(layout, context, brush, ui_editing=False, popover=False, show_reorder=None, filterkey="show_in_workspace",
+ parent="VIEW3D_PT_tools_brush_settings_channels", prefix="VIEW3D_PT_brush_category_"):
+ channels = get_ui_channels(brush.channels, [filterkey])
+
+ if show_reorder is None:
+ show_reorder = ui_editing
+
+ DynamicPaintPanelGen.ensureCategory("Basic", "Basic", parent=parent,
+ prefix=prefix, ui_editing=ui_editing,
+ show_reorder=show_reorder)
+
+ for ch in channels:
+ if len(ch.category) > 0:
+ DynamicPaintPanelGen.ensureCategory(ch.category, ch.category, parent=parent,
+ prefix=prefix, ui_editing=ui_editing,
+ show_reorder=show_reorder, show_mappings=True)
+ continue
+
+ # VIEW3D_PT_brush_category_edit_
+ UnifiedPaintPanel.channel_unified(layout.column(),
+ context,
+ brush,
+ ch.idname, show_reorder=show_reorder, expand=False, ui_editing=ui_editing, show_mappings=True)
def brush_settings_advanced(layout, context, brush, popover=False):
"""Draw advanced brush settings for Sculpt, Texture/Vertex/Weight Paint modes."""
@@ -1890,7 +2202,7 @@ def brush_basic_gpencil_vertex_settings(layout, _context, brush, *, compact=Fals
row.prop(gp_settings, "vertex_mode", text="Mode")
-classes = (VIEW3D_MT_tools_projectpaint_clone, BRUSH_PT_channel_panel)
+classes = [VIEW3D_MT_tools_projectpaint_clone, BRUSH_PT_channel_panel]
if __name__ == "__main__": # only for live edit.
from bpy.utils import register_class
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 62d62172170..67a97d9a1de 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -8,6 +8,7 @@ from bpy.types import (
from bl_ui.properties_paint_common import (
UnifiedPaintPanel,
brush_basic_texpaint_settings,
+ brush_settings_channels,
)
from bl_ui.properties_grease_pencil_common import (
AnnotationDataPanel,
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 892dc9a1e42..8be1aa36f70 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -20,6 +20,7 @@ from bl_ui.properties_paint_common import (
brush_settings,
brush_settings_advanced,
draw_color_settings,
+ brush_settings_channels,
)
from bl_ui.utils import PresetPanel
@@ -359,6 +360,29 @@ class VIEW3D_PT_tools_brush_select(Panel, View3DPaintBrushPanel, BrushSelectPane
bl_context = ".paint_common"
bl_label = "Brushes"
+class VIEW3D_PT_tools_brush_settings_channels(Panel, View3DPaintBrushPanel):
+ bl_context = ".paint_common"
+ bl_label = "Brush Settings"
+
+ @classmethod
+ def poll(cls, context):
+ settings = cls.paint_settings(context)
+
+ ok = settings and settings.brush is not None
+
+ return ok
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False # No animation.
+
+ settings = self.paint_settings(context)
+ brush = settings.brush
+
+ ui_editing = context.tool_settings.brush_editor_mode
+ brush_settings_channels(layout.column(), context, brush, popover=self.is_popover, ui_editing=ui_editing)
# TODO, move to space_view3d.py
class VIEW3D_PT_tools_brush_settings(Panel, View3DPaintBrushPanel):
@@ -379,6 +403,8 @@ class VIEW3D_PT_tools_brush_settings(Panel, View3DPaintBrushPanel):
settings = self.paint_settings(context)
brush = settings.brush
+ layout.prop(context.tool_settings, "brush_editor_mode")
+
brush_settings(layout.column(), context, brush, popover=self.is_popover)
@@ -435,6 +461,55 @@ class VIEW3D_PT_tools_brush_color(Panel, View3DPaintPanel):
draw_color_settings(context, layout, brush, color_type=not context.vertex_paint_object)
+class VIEW3D_PT_tools_persistent_base_channels(Panel, View3DPaintPanel):
+ bl_context = ".paint_common"
+ #bl_parent_id = "VIEW3D_PT_tools_brush_settings_channels"
+ bl_label = "Persistent Base"
+ bl_options = {'DEFAULT_CLOSED'}
+
+ @classmethod
+ def poll(cls, context):
+ settings = cls.paint_settings(context)
+ if not settings:
+ return False
+
+ brush = settings.brush
+
+ ch = UnifiedPaintPanel.get_channel(context, brush, "use_persistent")
+
+ capabilities = brush.sculpt_capabilities
+
+ ok = context.mode == "SCULPT"
+ ok = ok and ch and ch.show_in_workspace
+ ok = ok or capabilities.has_persistence
+
+ return ok
+
+ def draw(self, context):
+ layout = self.layout
+ settings = self.paint_settings(context)
+ brush = settings.brush
+ sculpt = context.tool_settings.sculpt
+
+ UnifiedPaintPanel.channel_unified(layout,
+ context,
+ brush,
+ "use_persistent",
+ #text="Weight By Face Area",
+ ui_editing=False)
+
+ layout.operator("sculpt.set_persistent_base")
+
+ if sculpt.has_persistent_base():
+ layout.label(text="Persistent base exists")
+ else:
+ layout.label(text="No persisent base data")
+
+class VIEW3D_PT_tools_brush_swatches_channels(Panel, View3DPaintPanel, ColorPalettePanel):
+ bl_context = ".paint_common"
+ bl_parent_id = "VIEW3D_PT_tools_brush_settings_channels"
+ bl_label = "Color Palette"
+ bl_options = {'DEFAULT_CLOSED'}
class VIEW3D_PT_tools_brush_swatches(Panel, View3DPaintPanel, ColorPalettePanel):
bl_context = ".paint_common"
@@ -2439,6 +2514,9 @@ classes = (
VIEW3D_PT_tools_grease_pencil_brush_vertex_color,
VIEW3D_PT_tools_grease_pencil_brush_vertex_palette,
VIEW3D_PT_tools_grease_pencil_brush_vertex_falloff,
+ VIEW3D_PT_tools_brush_settings_channels,
+ VIEW3D_PT_tools_persistent_base_channels,
+ VIEW3D_PT_tools_brush_swatches_channels,
)
if __name__ == "__main__": # only for live edit.
diff --git a/source/blender/blenkernel/BKE_brush_channel.h b/source/blender/blenkernel/BKE_brush_channel.h
index 9ffc11a8216..65e16afd045 100644
--- a/source/blender/blenkernel/BKE_brush_channel.h
+++ b/source/blender/blenkernel/BKE_brush_channel.h
@@ -25,6 +25,7 @@
* \brief New brush engine for sculpt
*/
+#include "BKE_paint.h"
#include "RNA_types.h"
/*
@@ -114,6 +115,10 @@ typedef struct BrushEnumDef {
const char description[512];
} BrushEnumDef;
+typedef struct BrushUIFlagDef {
+ int tools[100];
+} BrushUIFlagDef;
+
/*
Defines a brush channel. Includes limits, UI data,
default values, etc.
@@ -123,6 +128,8 @@ typedef struct BrushChannelType {
float min, max, soft_min, soft_max;
BrushMappingPreset mappings;
+ BrushUIFlagDef paint_mode_uiflags[PAINT_MODE_INVALID];
+
int type, flag, ui_flag;
int subtype;
@@ -131,7 +138,11 @@ typedef struct BrushChannelType {
BrushChannelSet *BKE_brush_channelset_create();
void BKE_brush_channelset_free(BrushChannelSet *chset);
-void BKE_brush_channelset_ensure_channels(BrushChannelSet *chset, int sculpt_tool);
+void BKE_brush_channelset_ensure_channels(BrushChannelSet *chset, ePaintMode mode, int tool);
+
+/* Calls BKE_brush_channelset_ensure_channels for every paint mode with a tool inside of brush. */
+void BKE_brush_channelset_ensure_all_modes(struct Brush *brush);
+
void BKE_brush_channelset_blend_read(BrushChannelSet *chset, struct BlendDataReader *reader);
void BKE_brush_channelset_blend_write(BrushChannelSet *chset, struct BlendWriter *writer);
/*
@@ -246,6 +257,10 @@ void _BKE_brush_channelset_mark_update(BrushChannelSet *chset, const char *idnam
*/
void BKE_brush_channelset_ui_order_check(BrushChannelSet *chset);
+void BKE_brush_channelset_ui_order_move(BrushChannelSet *chset,
+ BrushChannel *ch,
+ int uiflag,
+ int dir);
bool _BKE_brush_mapping_enabled(const struct Scene *scene,
const struct Brush *brush,
diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc
index a9e34702d1f..72e4093192f 100644
--- a/source/blender/blenkernel/intern/brush.cc
+++ b/source/blender/blenkernel/intern/brush.cc
@@ -60,6 +60,9 @@ static void brush_init_data(ID *id)
/* the default alpha falloff curve */
BKE_brush_curve_preset(brush, CURVE_PRESET_SMOOTH);
+
+ brush->channels = BKE_brush_channelset_create();
+ BKE_brush_channelset_ensure_channels(brush->channels, PAINT_MODE_INVALID, 0);
}
static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int flag)
@@ -104,6 +107,10 @@ static void brush_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
brush_dst->curves_sculpt_settings = MEM_cnew(__func__, *(brush_src->curves_sculpt_settings));
}
+ if (brush_src->channels) {
+ brush_dst->channels = BKE_brush_channelset_copy(brush_src->channels);
+ }
+
/* enable fake user by default */
id_fake_user_set(&brush_dst->id);
}
@@ -137,6 +144,10 @@ static void brush_free_data(ID *id)
MEM_SAFE_FREE(brush->gradient);
BKE_previewimg_free(&(brush->preview));
+
+ if (brush->channels) {
+ BKE_brush_channelset_free(brush->channels);
+ }
}
static void brush_make_local(Main *bmain, ID *id, const int flags)
@@ -334,16 +345,11 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &brush->channels);
- if (brush->sculpt_tool) {
- if (!brush->channels) {
- brush->channels = BKE_brush_channelset_create();
- }
- else {
- BKE_brush_channelset_blend_read(brush->channels, reader);
- }
-
- BKE_brush_channelset_ensure_channels(brush->channels, brush->sculpt_tool);
+ if (brush->channels) {
+ BKE_brush_channelset_blend_read(brush->channels, reader);
}
+
+ BKE_brush_channelset_ensure_all_modes(brush);
}
static void brush_blend_read_lib(BlendLibReader *reader, ID *id)
@@ -1718,7 +1724,7 @@ void BKE_brush_sculpt_reset(Brush *br)
}
br->channels = BKE_brush_channelset_create();
- BKE_brush_channelset_ensure_channels(br->channels, br->sculpt_tool);
+ BKE_brush_channelset_ensure_channels(br->channels, PAINT_MODE_SCULPT, br->sculpt_tool);
/* Use the curve presets by default */
br->curve_preset = BRUSH_CURVE_SMOOTH;
@@ -2311,7 +2317,7 @@ bool BKE_brush_use_size_pressure(const Scene *scene, const Brush *brush)
return BKE_brush_mapping_enabled(scene, brush, unprojected_radius, BRUSH_MAPPING_PRESSURE);
}
- //return brush->flag & BRUSH_SIZE_PRESSURE;
+ // return brush->flag & BRUSH_SIZE_PRESSURE;
}
bool BKE_brush_use_alpha_pressure(const Brush *brush)
diff --git a/source/blender/blenkernel/intern/brush_channel.cc b/source/blender/blenkernel/intern/brush_channel.cc
index 9d41b6005b4..35fd62ba34d 100644
--- a/source/blender/blenkernel/intern/brush_channel.cc
+++ b/source/blender/blenkernel/intern/brush_channel.cc
@@ -34,9 +34,11 @@
#include "BKE_idprop.hh"
#include "BKE_lib_id.h"
#include "BKE_paint.h"
+#include "BKE_pbvh.h"
#include "BLO_read_write.h"
#include <string>
+#include <vector>
const char builtin_brush_categories[][128] = {"Basic", "Smooth", "Color"};
@@ -60,21 +62,87 @@ static Map<StringRef, BrushChannelType> builtin_channels;
using ChannelNameMap = Map<StringRef, BrushChannel *>;
-static void init_builtin_brush_channels()
+ATTR_NO_OPT static void init_builtin_brush_channels()
{
+ struct UI {
+ int mode;
+ Vector<int> tools;
+ int uiflag;
+ bool all_tool_modes = false;
+ bool all_tools = false;
+ bool exists = true;
+
+ UI(const UI &b)
+ {
+ tools = b.tools;
+ uiflag = b.uiflag;
+ all_tool_modes = b.all_tool_modes;
+ all_tools = b.all_tools;
+ exists = b.exists;
+ mode = b.mode;
+ }
+
+ UI(int _mode, int _uiflag, int _tool) : mode(_mode), uiflag(_uiflag)
+ {
+ tools.append(_tool);
+ }
+
+ UI(int _uiflag) : uiflag(_uiflag)
+ {
+ all_tool_modes = all_tools = true;
+ }
+
+ UI(ePaintMode _mode, int _uiflag) : mode((int)_mode), uiflag(_uiflag)
+ {
+ all_tools = true;
+ }
+
+ UI(ePaintMode mode, int uiflag, int tool)
+ {
+ UI::UI((int)mode, uiflag, tool);
+ }
+
+ UI(ePaintMode _mode, int _uiflag, Vector<int> _tools)
+ : mode((int)_mode), tools(_tools), uiflag(_uiflag)
+ {
+ }
+ };
+
struct ChannelProp {
char path[512];
char category[64];
- int uiflag;
+ Vector<UI> extra_uiflags;
int flag;
BrushMappingPreset mappings;
};
+#ifdef BRUSH_CHANNEL_DEFINE_EXTERNAL
+# undef BRUSH_CHANNEL_DEFINE_EXTERNAL
+#endif
+
+#ifdef BRUSH_CHANNEL_DEFINE_INTERNAL_NAMES
+# undef BRUSH_CHANNEL_DEFINE_INTERNAL_NAMES
+#endif
+#ifdef MAKE_PROP
+# undef MAKE_PROP
+#endif
+#ifdef MAKE_PROP_EX
+# undef MAKE_PROP_EX
+#endif
+
+ //#define MAKE_PROP(idname, category, uiflags) MAKE_PROP_EX(idname, category, uiflags, 0)
+
+ //#define SHOW_CONTEXT BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU
+ //#define SHOW_WORKSPACE BRUSH_CHANNEL_SHOW_IN_WORKSPACE
+
#define BRUSH_CHANNEL_DEFINE_INTERNAL
ChannelProp channel_props[] = {
#include "brush_channel_define.h"
};
+#undef SHOW_CONTEXT
+#undef SHOW_WORKSPACE
+
StructRNA *srna = RNA_struct_find("Brush");
Brush dummy = {0};
@@ -84,12 +152,32 @@ static void init_builtin_brush_channels()
for (int i : IndexRange(ARRAY_SIZE(channel_props))) {
ChannelProp &def = channel_props[i];
- BrushChannelType type;
+ BrushChannelType type = {0};
BLI_strncpy(type.idname, def.path, sizeof(type.idname));
BLI_strncpy(type.category, def.category, sizeof(type.category));
type.flag = def.flag;
- type.ui_flag = def.uiflag;
+
+ for (auto &ui : def.extra_uiflags) {
+ for (int mode = 0; mode < (int)PAINT_MODE_INVALID; mode++) {
+ if (mode != ui.mode && !ui.all_tool_modes) {
+ continue;
+ }
+
+ int uiflag = ui.uiflag ? ui.uiflag : -1;
+
+ if (ui.all_tools) {
+ for (int j = 0; j < ARRAY_SIZE(type.paint_mode_uiflags); j++) {
+ type.paint_mode_uiflags[mode].tools[j] = uiflag;
+ }
+ }
+ else {
+ for (auto tool : ui.tools) {
+ type.paint_mode_uiflags[mode].tools[tool] = uiflag;
+ }
+ }
+ }
+ }
PropertyRNA *prop = RNA_struct_type_find_property(srna, def.path);
BLI_assert(prop);
@@ -111,6 +199,9 @@ static void init_builtin_brush_channels()
type.soft_max = 1.0;
switch (prop_type) {
+ case PROP_BOOLEAN:
+ type.type = BRUSH_CHANNEL_TYPE_BOOL;
+ break;
case PROP_INT: {
int min, max, soft_min, soft_max;
int step;
@@ -329,15 +420,70 @@ ATTR_NO_OPT BrushChannel *_BKE_brush_channelset_ensure(BrushChannelSet *chset, c
return _BKE_brush_channelset_lookup(chset, idname);
}
-void BKE_brush_channelset_ensure_channels(BrushChannelSet *chset, int sculpt_tool)
+void BKE_brush_channelset_ensure_all_modes(Brush *brush)
+{
+ if (!brush->channels) {
+ brush->channels = BKE_brush_channelset_create();
+ BKE_brush_channelset_ensure_channels(brush->channels, PAINT_MODE_INVALID, 0);
+ }
+
+ if (brush->sculpt_tool) {
+ BKE_brush_channelset_ensure_channels(brush->channels, PAINT_MODE_SCULPT, brush->sculpt_tool);
+ }
+
+ if (brush->vertexpaint_tool) {
+ BKE_brush_channelset_ensure_channels(
+ brush->channels, PAINT_MODE_VERTEX, brush->vertexpaint_tool);
+ }
+
+ if (brush->imagepaint_tool) {
+ BKE_brush_channelset_ensure_channels(
+ brush->channels, PAINT_MODE_TEXTURE_3D, brush->imagepaint_tool);
+ }
+
+ if (brush->curves_sculpt_tool) {
+ BKE_brush_channelset_ensure_channels(
+ brush->channels, PAINT_MODE_SCULPT_CURVES, brush->curves_sculpt_tool);
+ }
+
+ if (brush->weightpaint_tool) {
+ BKE_brush_channelset_ensure_channels(
+ brush->channels, PAINT_MODE_WEIGHT, brush->weightpaint_tool);
+ }
+}
+void BKE_brush_channelset_ensure_channels(BrushChannelSet *chset, ePaintMode mode, int tool)
{
check_builtin_brush_channels();
BKE_brush_channelset_ensure(chset, size);
BKE_brush_channelset_ensure(chset, unprojected_radius);
BKE_brush_channelset_ensure(chset, strength);
- BKE_brush_channelset_ensure(chset, auto_smooth_factor);
+ BKE_brush_channelset_ensure(chset, spacing);
+
+ if (mode != PAINT_MODE_INVALID) {
+ for (BrushChannelType &type : builtin_channels.values()) {
+ int uiflag = type.paint_mode_uiflags[(int)mode].tools[tool];
+ if (uiflag) {
+ BrushChannel *ch = _BKE_brush_channelset_ensure(chset, type.idname);
+
+ if (uiflag != -1) {
+ if (!(ch->ui_flag & BRUSH_CHANNEL_SHOW_IN_HEADER_USER_SET)) {
+ ch->ui_flag &= ~BRUSH_CHANNEL_SHOW_IN_HEADER;
+ ch->ui_flag |= uiflag & BRUSH_CHANNEL_SHOW_IN_HEADER;
+ }
+ if (!(ch->ui_flag & BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU_USER_SET)) {
+ ch->ui_flag &= ~BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU;
+ ch->ui_flag |= uiflag & BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU;
+ }
+ if (!(ch->ui_flag & BRUSH_CHANNEL_SHOW_IN_WORKSPACE_USER_SET)) {
+ ch->ui_flag &= ~BRUSH_CHANNEL_SHOW_IN_WORKSPACE;
+ ch->ui_flag |= uiflag & BRUSH_CHANNEL_SHOW_IN_WORKSPACE;
+ }
+ }
+ }
+ }
+ }
/* Some helper lambdas */
auto _ensure = [&](const char *idname) { return _BKE_brush_channelset_ensure(chset, idname); };
@@ -368,16 +514,18 @@ void BKE_brush_channelset_ensure_channels(BrushChannelSet *chset, int sculpt_too
const int SHOW_HEADER = BRUSH_CHANNEL_SHOW_IN_HEADER;
const int SHOW_ALL = (SHOW_WORKSPACE | SHOW_CONTEXT | SHOW_HEADER);
- switch (sculpt_tool) {
- case SCULPT_TOOL_PAINT:
- ensure_ui(wet_mix, SHOW_WORKSPACE);
- ensure_ui(wet_persistence, SHOW_WORKSPACE);
- ensure_ui(color, SHOW_ALL);
- ensure_ui(secondary_color, SHOW_ALL);
- ensure_ui(flow, SHOW_WORKSPACE | SHOW_CONTEXT);
- ensure_ui(density, SHOW_WORKSPACE | SHOW_CONTEXT);
- ensure_ui(tip_scale_x, SHOW_WORKSPACE | SHOW_CONTEXT);
- break;
+ if (mode == PAINT_MODE_SCULPT) {
+ switch (tool) {
+ case SCULPT_TOOL_PAINT:
+ ensure_ui(wet_mix, SHOW_WORKSPACE);
+ ensure_ui(wet_persistence, SHOW_WORKSPACE);
+ ensure_ui(color, SHOW_ALL);
+ ensure_ui(secondary_color, SHOW_ALL);
+ ensure_ui(flow, SHOW_WORKSPACE | SHOW_CONTEXT);
+ ensure_ui(density, SHOW_WORKSPACE | SHOW_CONTEXT);
+ ensure_ui(tip_scale_x, SHOW_WORKSPACE | SHOW_CONTEXT);
+ break;
+ }
}
#undef ensure
@@ -1001,14 +1149,23 @@ void BKE_brush_channelset_toolsettings_init(ToolSettings *ts)
PointerRNA prop_ptr;
PropertyRNA *prop;
double default_value = 0.0;
+ float vector4[4] = {0.0f, 0.0f, 0.0f, 0.0f};
if (RNA_path_resolve(&ptr, ch->idname, &prop_ptr, &prop)) {
switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ default_value = RNA_boolean_get(&prop_ptr, ch->idname) ? 1.0 : 0.0;
+ break;
case PROP_INT:
default_value = RNA_int_get(&prop_ptr, ch->idname);
break;
case PROP_FLOAT:
- default_value = RNA_float_get(&prop_ptr, ch->idname);
+ if (RNA_property_array_check(prop)) {
+ RNA_float_get_array(&prop_ptr, ch->idname, vector4);
+ }
+ else {
+ default_value = RNA_float_get(&prop_ptr, ch->idname);
+ }
break;
case PROP_ENUM:
default_value = (double)RNA_enum_get(&prop_ptr, ch->idname);
@@ -1034,14 +1191,25 @@ void BKE_brush_channelset_toolsettings_init(ToolSettings *ts)
tmpl.i = (int)default_value;
type = IDP_INT;
break;
+ case BRUSH_CHANNEL_TYPE_VEC4:
+ tmpl.array.type = IDP_FLOAT;
+ tmpl.array.len = 4;
+ type = IDP_ARRAY;
+ break;
default:
- printf(
- "%s: unsupported brush channel type for unified channel: %d\n", __func__, ch->type);
+ printf("%s: unsupported brush channel type for unified channel %s: %d\n",
+ __func__,
+ ch->idname,
+ ch->type);
continue;
}
idprop = IDP_New(type, &tmpl, ch->idname);
IDP_AddToGroup(ts->unified_properties, idprop);
+
+ if (ch->type == BRUSH_CHANNEL_TYPE_VEC4) {
+ memcpy(idprop->data.pointer, static_cast<void *>(vector4), sizeof(vector4));
+ }
}
IDPropertyUIData *uidata = IDP_ui_data_ensure(idprop);
@@ -1082,7 +1250,14 @@ void BKE_brush_channelset_toolsettings_init(ToolSettings *ts)
}
case BRUSH_CHANNEL_TYPE_ENUM:
case BRUSH_CHANNEL_TYPE_BITMASK:
+ break;
case BRUSH_CHANNEL_TYPE_BOOL: {
+ IDPropertyUIDataInt *uidatai = reinterpret_cast<IDPropertyUIDataInt *>(uidata);
+
+ uidatai->min = uidatai->soft_min = 0;
+ uidatai->max = uidatai->soft_max = 1;
+ uidatai->step = 1;
+
break;
}
}
@@ -1114,12 +1289,66 @@ void BKE_brush_channelset_ui_order_check(BrushChannelSet *chset)
return ch1->ui_order < ch2->ui_order;
};
- std::sort(channels.begin(), channels.end());
+ std::sort(channels.begin(), channels.end(), cmp);
+
for (int i = 0; i < channels.size(); i++) {
channels[i]->ui_order = i;
}
}
+void BKE_brush_channelset_ui_order_move(BrushChannelSet *chset,
+ BrushChannel *ch,
+ int uiflag,
+ int dir)
+{
+ Vector<BrushChannel *> channels;
+
+ LISTBASE_FOREACH (BrushChannel *, ch, &chset->channels) {
+ channels.append(ch);
+ }
+
+ auto cmp = [](const BrushChannel *ch1, const BrushChannel *ch2) {
+ return ch1->ui_order < ch2->ui_order;
+ };
+
+ std::sort(channels.begin(), channels.end(), cmp);
+
+ const char *cat1 = BKE_brush_channel_category_get(ch);
+
+ for (int i = 0; i < channels.size(); i++) {
+ if (channels[i] == ch) {
+ int j = i;
+ BrushChannel *ch2 = NULL;
+ const char *cat2;
+
+ do {
+ j += dir < 0 ? -1 : 1;
+
+ if (j < 0 || j >= channels.size()) {
+ break;
+ }
+
+ ch2 = channels[j];
+ cat2 = BKE_brush_channel_category_get(ch2);
+ } while ((!(ch2->ui_flag & uiflag) || !STREQ(cat1, cat2)));
+
+ int neworder;
+
+ if (ch2) {
+ neworder = ch2->ui_order;
+ ch2->ui_order = ch->ui_order;
+ }
+ else {
+ neworder = dir < 0 ? 0 : channels.size();
+ }
+
+ ch->ui_order = neworder;
+ }
+ }
+
+ BKE_brush_channelset_ui_order_check(chset);
+}
+
#if 0
void BKE_brush_channels_update(Brush *active_brush, Scene *scene)
{
diff --git a/source/blender/blenkernel/intern/brush_channel_define.h b/source/blender/blenkernel/intern/brush_channel_define.h
index ce8ab43c65c..4caf74d1077 100644
--- a/source/blender/blenkernel/intern/brush_channel_define.h
+++ b/source/blender/blenkernel/intern/brush_channel_define.h
@@ -1,19 +1,22 @@
-#ifdef MAKE_PROP
-# undef MAKE_PROP
-#endif
-#ifdef MAKE_PROP_EX
-# undef MAKE_PROP_EX
+#if defined(BRUSH_CHANNEL_DEFINE_EXTERNAL) || defined(BRUSH_CHANNEL_DEFINE_INTERNAL_NAMES) || \
+ defined(BRUSH_CHANNEL_DEFINE_INTERNAL)
+# ifdef MAKE_PROP
+# undef MAKE_PROP
+# endif
+# ifdef MAKE_PROP_EX
+# undef MAKE_PROP_EX
+# endif
#endif
#ifdef BRUSH_CHANNEL_DEFINE_EXTERNAL
-# define MAKE_PROP(idname, category, uiflag) extern const char *BRUSH_BUILTIN_##idname;
-# define MAKE_PROP_EX(idname, category, uiflag, flag) MAKE_PROP(idname)
+# define MAKE_PROP_EX(idname, category, flag, ...) MAKE_PROP(idname, category, uiflags)
+# define MAKE_PROP(idname, category, ...) extern const char *BRUSH_BUILTIN_##idname;
#elif defined(BRUSH_CHANNEL_DEFINE_INTERNAL_NAMES)
-# define MAKE_PROP(idname, category, uiflag) const char *BRUSH_BUILTIN_##idname = # idname;
-# define MAKE_PROP_EX(idname, category, uiflag, flag) MAKE_PROP(idname)
+# define MAKE_PROP_EX(idname, category, flag, ...) MAKE_PROP(idname, category)
+# define MAKE_PROP(idname, category, ...) const char *BRUSH_BUILTIN_##idname = # idname;
#elif defined(BRUSH_CHANNEL_DEFINE_INTERNAL)
-# define MAKE_PROP_EX(idname, category, uiflag, flag) {# idname, category, uiflag, flag, {}},
-# define MAKE_PROP(idname, category, uiflag) MAKE_PROP_EX(idname, category, uiflag, 0)
+# define MAKE_PROP(idname, category, ...) {# idname, category, {__VA_ARGS__}, 0, {}},
+# define MAKE_PROP_EX(idname, category, flag, ...) {# idname, category, {__VA_ARGS__}, flag, {}},
#endif
@@ -27,7 +30,7 @@
# undef SHOW_CONTEXT
#endif
#ifdef SHOW_ALL
-#undef SHOW_ALL
+# undef SHOW_ALL
#endif
/*
@@ -44,20 +47,189 @@
* BKE_brush_channelset_ensure_channels
*/
-MAKE_PROP(size, "Basic", SHOW_ALL)
-MAKE_PROP(unprojected_radius, "Basic", SHOW_ALL)
-MAKE_PROP(strength, "Basic", SHOW_ALL)
-MAKE_PROP(auto_smooth_factor, "Smooth", SHOW_WORKSPACE | SHOW_CONTEXT)
-MAKE_PROP(density, "Basic", 0)
-MAKE_PROP(tip_scale_x, "Basic", 0)
+#define SCULPT_GEO_TOOLS \
+ SCULPT_TOOL_DRAW, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_STRIPS, SCULPT_TOOL_FLATTEN, \
+ SCULPT_TOOL_PINCH, SCULPT_TOOL_FILL, SCULPT_TOOL_INFLATE, SCULPT_TOOL_THUMB, \
+ SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_CREASE, SCULPT_TOOL_BLOB, SCULPT_TOOL_CLAY_STRIPS, \
+ SCULPT_TOOL_LAYER
+
+#ifdef GEOMETRY
+#undef GEOMETRY
+#endif
+
+#define GEOMETRY(flag) UI(PAINT_MODE_SCULPT, flag, {SCULPT_GEO_TOOLS})
+
+#ifdef AUTOMASKING
+# undef AUTOMASKING
+#endif
+#define AUTOMASKING UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE)
+
+#ifdef SCULPT_PAINT
+# undef SCULPT_PAINT
+#endif
+#ifdef SCULPT_CLOTHABLE_TOOLS
+# undef SCULPT_CLOTHABLE_TOOLS
+#endif
+
+#define SCULPT_CLOTHABLE_TOOLS \
+ SCULPT_TOOL_CLOTH, SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_ELASTIC_DEFORM, SCULPT_TOOL_POSE
+
+#define SCULPT_PAINT UI(PAINT_MODE_SCULPT, SHOW_CONTEXT | SHOW_WORKSPACE, {SCULPT_TOOL_PAINT})
+
+MAKE_PROP(size, "Basic", UI(SHOW_ALL))
+MAKE_PROP(unprojected_radius, "Basic", UI(SHOW_ALL))
+MAKE_PROP(strength, "Basic", UI(SHOW_ALL))
+MAKE_PROP(automasking_boundary_edges_propagation_steps, "Automasking", AUTOMASKING)
+MAKE_PROP(use_automasking_boundary_edges, "Automasking", AUTOMASKING)
+MAKE_PROP(use_automasking_boundary_face_sets, "Automasking", AUTOMASKING)
+MAKE_PROP(use_automasking_face_sets, "Automasking", AUTOMASKING)
+MAKE_PROP(use_automasking_topology, "Automasking", AUTOMASKING)
+MAKE_PROP(area_radius_factor, "Basic", GEOMETRY(SHOW_WORKSPACE|SHOW_CONTEXT))
+MAKE_PROP(blur_kernel_radius, "Basic")
+MAKE_PROP(boundary_offset, "Basic", UI(PAINT_MODE_SCULPT, SHOW_ALL, {SCULPT_TOOL_BOUNDARY}))
+MAKE_PROP(clone_alpha,
+ "Basic",
+ UI(PAINT_MODE_TEXTURE_2D, SHOW_WORKSPACE),
+ UI(PAINT_MODE_TEXTURE_3D, SHOW_WORKSPACE))
+MAKE_PROP(clone_offset,
+ "Basic",
+ UI(PAINT_MODE_TEXTURE_2D, SHOW_WORKSPACE),
+ UI(PAINT_MODE_TEXTURE_3D, SHOW_WORKSPACE))
+MAKE_PROP(crease_pinch_factor, "Basic")
+MAKE_PROP(cursor_color_add, "Basic")
+MAKE_PROP(cursor_color_subtract, "Basic")
+MAKE_PROP(cursor_overlay_alpha, "Basic")
+MAKE_PROP(disconnected_distance_max, "Basic")
+MAKE_PROP(elastic_deform_volume_preservation,
+ "Basic",
+ UI(PAINT_MODE_SCULPT,
+ SHOW_WORKSPACE,
+ {SCULPT_TOOL_ELASTIC_DEFORM | SCULPT_TOOL_BOUNDARY | SCULPT_TOOL_CLOTH}))
+MAKE_PROP(falloff_angle, "Basic")
+MAKE_PROP(fill_threshold, "Basic")
+MAKE_PROP(flow, "Basic")
+MAKE_PROP(grad_spacing, "Basic")
+MAKE_PROP(hardness, "Basic")
+MAKE_PROP(height, "Basic", UI(PAINT_MODE_SCULPT, SHOW_ALL, {SCULPT_TOOL_LAYER}))
+MAKE_PROP(invert_to_scrape_fill, "Basic")
+MAKE_PROP(mask_overlay_alpha, "Basic")
+MAKE_PROP(mask_stencil_dimension, "Basic")
+MAKE_PROP(mask_stencil_pos, "Basic")
+MAKE_PROP(multiplane_scrape_angle, "Basic")
+MAKE_PROP(normal_radius_factor, "Basic")
+MAKE_PROP(normal_weight, "Basic")
+MAKE_PROP(plane_offset, "Basic")
+MAKE_PROP(plane_trim, "Basic")
+MAKE_PROP(rake_factor, "Basic")
+MAKE_PROP(sharp_threshold, "Basic")
+MAKE_PROP(show_multiplane_scrape_planes_preview, "Basic")
+MAKE_PROP(stencil_dimension, "Basic")
+MAKE_PROP(stencil_pos, "Basic")
+MAKE_PROP(surface_smooth_current_vertex, "Basic")
+MAKE_PROP(surface_smooth_iterations, "Basic")
+MAKE_PROP(surface_smooth_shape_preservation, "Basic")
+MAKE_PROP(texture_overlay_alpha, "Basic")
+MAKE_PROP(texture_sample_bias, "Basic")
+MAKE_PROP(tilt_strength_factor, "Basic")
+MAKE_PROP(tip_roundness, "Basic")
+MAKE_PROP(tip_scale_x, "Basic")
+MAKE_PROP(use_accumulate, "Basic", UI(SHOW_ALL))
+MAKE_PROP(use_adaptive_space, "Basic")
+MAKE_PROP(use_airbrush, "Basic")
+MAKE_PROP(use_alpha, "Basic")
+MAKE_PROP(use_anchor, "Basic")
+MAKE_PROP(use_connected_only, "Basic")
+MAKE_PROP(use_cursor_overlay, "Basic")
+MAKE_PROP(use_cursor_overlay_override, "Basic")
+MAKE_PROP(use_curve, "Basic")
+MAKE_PROP(use_custom_icon, "Basic")
+MAKE_PROP(use_edge_to_edge, "Basic")
+MAKE_PROP(use_frontface, "Basic")
+MAKE_PROP(use_frontface_falloff, "Basic")
+MAKE_PROP(use_grab_active_vertex, "Basic")
+MAKE_PROP(use_grab_silhouette, "Basic")
+MAKE_PROP(use_line, "Basic")
+MAKE_PROP(use_multiplane_scrape_dynamic, "Basic")
+MAKE_PROP(use_original_normal, "Basic")
+MAKE_PROP(use_original_plane, "Basic")
+MAKE_PROP(use_persistent, "Basic")
+MAKE_PROP(use_plane_trim, "Basic")
+MAKE_PROP(use_primary_overlay, "Basic")
+MAKE_PROP(use_primary_overlay_override, "Basic")
+MAKE_PROP(use_restore_mesh, "Basic")
+MAKE_PROP(use_secondary_overlay, "Basic")
+MAKE_PROP(use_secondary_overlay_override, "Basic")
+MAKE_PROP(use_smooth_stroke, "Basic", UI(SHOW_WORKSPACE))
+MAKE_PROP(use_space, "Basic", UI(SHOW_WORKSPACE))
+MAKE_PROP(use_space_attenuation, "Basic", UI(SHOW_WORKSPACE))
+MAKE_PROP(use_vertex_grease_pencil, "Basic")
+MAKE_PROP(weight, "Basic")
+MAKE_PROP(wet_paint_radius_factor, "Basic")
+MAKE_PROP(cloth_constraint_softbody_strength,
+ "Cloth",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(cloth_damping, "Cloth", UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(cloth_mass, "Cloth", UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(cloth_sim_falloff,
+ "Cloth",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(cloth_sim_limit,
+ "Cloth",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(use_cloth_collision,
+ "Cloth",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(use_cloth_pin_simulation_boundary,
+ "Cloth",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_CLOTHABLE_TOOLS}))
+MAKE_PROP(color,
+ "Paint",
+ UI(PAINT_MODE_SCULPT, SHOW_ALL, {SCULPT_TOOL_PAINT}),
+ UI(PAINT_MODE_TEXTURE_2D, SHOW_ALL),
+ UI(PAINT_MODE_TEXTURE_3D, SHOW_ALL),
+ UI(PAINT_MODE_VERTEX, SHOW_ALL))
+MAKE_PROP(density, "Paint", SCULPT_PAINT)
+MAKE_PROP(rate, "Paint")
+MAKE_PROP(secondary_color,
+ "Paint",
+ UI(PAINT_MODE_SCULPT, SHOW_ALL, {SCULPT_TOOL_PAINT}),
+ UI(PAINT_MODE_TEXTURE_2D, SHOW_ALL),
+ UI(PAINT_MODE_TEXTURE_3D, SHOW_ALL),
+ UI(PAINT_MODE_VERTEX, SHOW_ALL))
+MAKE_PROP(use_paint_antialiasing, "Paint", UI(PAINT_MODE_TEXTURE_2D, SHOW_WORKSPACE))
+MAKE_PROP(use_paint_weight, "Paint")
+MAKE_PROP(wet_mix, "Paint", SCULPT_PAINT)
+MAKE_PROP(wet_persistence, "Paint", SCULPT_PAINT)
+MAKE_PROP(pose_ik_segments, "Pose", UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_TOOL_POSE}))
+MAKE_PROP(pose_offset, "Pose", UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_TOOL_POSE}))
+MAKE_PROP(pose_smooth_iterations,
+ "Pose",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_TOOL_POSE}))
+MAKE_PROP(use_pose_ik_anchored, "Pose", UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_TOOL_POSE}))
+MAKE_PROP(use_pose_lock_rotation,
+ "Pose",
+ UI(PAINT_MODE_SCULPT, SHOW_WORKSPACE, {SCULPT_TOOL_POSE}))
+MAKE_PROP(auto_smooth_factor, "Smooth", GEOMETRY(SHOW_WORKSPACE | SHOW_CONTEXT))
+MAKE_PROP(topology_rake_factor, "Smooth", GEOMETRY(SHOW_WORKSPACE))
+MAKE_PROP(dash_ratio, "Stroke", UI(SHOW_WORKSPACE))
+MAKE_PROP(dash_samples, "Stroke", UI(SHOW_WORKSPACE))
+MAKE_PROP(jitter, "Stroke", UI(SHOW_WORKSPACE))
+MAKE_PROP(jitter_absolute, "Stroke", UI(SHOW_WORKSPACE))
+MAKE_PROP(smooth_stroke_factor, "Stroke", UI(SHOW_WORKSPACE))
+MAKE_PROP(smooth_stroke_radius, "Stroke", UI(SHOW_WORKSPACE))
+MAKE_PROP(spacing, "Stroke", UI(SHOW_WORKSPACE))
+
-MAKE_PROP(color, "Color", 0)
-MAKE_PROP(secondary_color, "Color", 0)
-MAKE_PROP(wet_mix, "Color", 0)
-MAKE_PROP(flow, "Color", 0)
-MAKE_PROP(wet_persistence, "Color", 0)
+// tst
+#undef MAKE_PROP
+#undef MAKE_PROP_EX
#undef SHOW_WORKSPACE
#undef SHOW_HEADER
#undef SHOW_CONTEXT
#undef SHOW_ALL
+#undef AUTOMASKING
+#undef SCULPT_GEO_TOOLS
+#undef SCULPT_PAINT
+#undef SCULPT_CLOTHABLE_TOOLS
+#undef GEOMETRY
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index a60afe66ba3..83a32f63950 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -1394,7 +1394,7 @@ static int change_channel_order_exec(bContext *C, wmOperator *op)
Brush *brush = BKE_paint_brush(paint);
char idname[BRUSH_CHANNEL_MAX_IDNAME];
- RNA_string_get(op->ptr, "idname", idname);
+ RNA_string_get(op->ptr, "channel", idname);
if (!_BKE_brush_channelset_has(brush->channels, idname)) {
static char error[128];
@@ -1408,27 +1408,23 @@ static int change_channel_order_exec(bContext *C, wmOperator *op)
int neworder = dest_ch->ui_order;
BKE_brush_channelset_ui_order_check(brush->channels);
+ char filterkey[64];
+ int uiflag = 0;
- int dir = RNA_int_get(op->ptr, "direction");
-
- if (dir < 0) {
- neworder = (neworder - 1 + brush->channels->channels_num) % brush->channels->channels_num;
+ RNA_string_get(op->ptr, "filterkey", filterkey);
+ if (STREQ(filterkey, "show_in_workspace")) {
+ uiflag = BRUSH_CHANNEL_SHOW_IN_WORKSPACE;
}
- else {
- neworder = (neworder + 1) % brush->channels->channels_num;
+ else if (STREQ(filterkey, "show_in_header")) {
+ uiflag = BRUSH_CHANNEL_SHOW_IN_HEADER;
}
-
- LISTBASE_FOREACH (BrushChannel *, ch, &brush->channels->channels) {
- if (ch == dest_ch) {
- continue;
- }
-
- if (ch->ui_order == neworder) {
- ch->ui_order = dest_ch->ui_order;
- }
+ else if (STREQ(filterkey, "show_in_context_menu")) {
+ uiflag = BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU;
}
- dest_ch->ui_order = neworder;
+ int dir = RNA_int_get(op->ptr, "direction");
+
+ BKE_brush_channelset_ui_order_move(brush->channels, dest_ch, uiflag, dir);
return OPERATOR_FINISHED;
}
@@ -1449,6 +1445,7 @@ void BRUSH_OT_change_channel_order(wmOperatorType *ot)
RNA_def_string(ot->srna, "channel", "", BRUSH_CHANNEL_MAX_IDNAME, "Brush Channel", "");
RNA_def_int(ot->srna, "direction", 1, -1, 1, "Direction", "", -1, 1);
+ RNA_def_string(ot->srna, "filterkey", NULL, 64, "filterkey", "filterkey");
}
/**************************** registration **********************************/
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 83a858fb7ea..f6e7cb6328c 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1575,6 +1575,8 @@ typedef struct ToolSettings {
struct SequencerToolSettings *sequencer_tool_settings;
+ char brush_editor_mode;
+ char _pad9[7];
} ToolSettings;
/* *************************************************************** */
diff --git a/source/blender/makesrna/intern/rna_brush_channels.c b/source/blender/makesrna/intern/rna_brush_channels.c
index d6446e20e1f..09d2c412f3f 100644
--- a/source/blender/makesrna/intern/rna_brush_channels.c
+++ b/source/blender/makesrna/intern/rna_brush_channels.c
@@ -481,12 +481,7 @@ static void channel_uiflag_set(PointerRNA *ptr, bool value, int flag, int user_s
ch->ui_flag &= ~flag;
}
- if ((ch->ui_flag & flag) != (ch->def->ui_flag & flag)) {
- ch->ui_flag |= user_set_flag;
- }
- else {
- ch->ui_flag &= ~BRUSH_CHANNEL_SHOW_IN_HEADER_USER_SET;
- }
+ ch->ui_flag |= user_set_flag;
}
void rna_BrushChannel_show_in_header_set(PointerRNA *ptr, bool value)
@@ -563,11 +558,7 @@ void RNA_def_brush_mapping(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Max", "");
static EnumPropertyItem inherit_mode_items[] = {
- {BRUSH_MAPPING_INHERIT_NEVER,
- "NEVER",
- ICON_NONE,
- "Never",
- "Never use unified settings."},
+ {BRUSH_MAPPING_INHERIT_NEVER, "NEVER", ICON_NONE, "Never", "Never use unified settings."},
{BRUSH_MAPPING_INHERIT_ALWAYS,
"ALWAYS",
ICON_NONE,
@@ -776,20 +767,21 @@ void RNA_def_brush_channel(BlenderRNA *brna)
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
prop = RNA_def_property(srna, "show_in_header", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, "BrushChannel", "flag", BRUSH_CHANNEL_SHOW_IN_HEADER);
+ RNA_def_property_boolean_sdna(prop, "BrushChannel", "ui_flag", BRUSH_CHANNEL_SHOW_IN_HEADER);
RNA_def_property_ui_text(prop, "In Header", "Show in header");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_boolean_funcs(prop, NULL, "rna_BrushChannel_show_in_header_set");
prop = RNA_def_property(srna, "show_in_workspace", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, "BrushChannel", "flag", BRUSH_CHANNEL_SHOW_IN_WORKSPACE);
+ RNA_def_property_boolean_sdna(prop, "BrushChannel", "ui_flag", BRUSH_CHANNEL_SHOW_IN_WORKSPACE);
RNA_def_property_ui_text(prop, "In Workspace", "Show in workspace");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_boolean_funcs(prop, NULL, "rna_BrushChannel_show_in_workspace_set");
prop = RNA_def_property(srna, "show_in_context_menu", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, "BrushChannel", "flag", BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU);
+ RNA_def_property_boolean_sdna(
+ prop, "BrushChannel", "ui_flag", BRUSH_CHANNEL_SHOW_IN_CONTEXT_MENU);
RNA_def_property_ui_text(prop, "In Workspace", "Show in workspace");
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_boolean_funcs(prop, NULL, "rna_BrushChannel_show_in_context_menu_set");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index ea02e8cf843..f70e6c0c915 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -3083,6 +3083,10 @@ static void rna_def_tool_settings(BlenderRNA *brna)
rna_def_unified_brush_properties(brna);
+ prop = RNA_def_property(srna, "brush_editor_mode", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "brush_editor_mode", 1);
+ RNA_def_property_ui_text(prop, "Brush Editor Mode", "");
+
prop = RNA_def_property(srna, "unified_properties", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "UnifiedBrushProperties");
RNA_def_property_ui_text(prop, "Unified Brush Property Storage", "");