diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_paint_common.py | 318 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d.py | 1 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 78 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_brush_channel.h | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.cc | 28 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush_channel.cc | 269 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush_channel_define.h | 218 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_ops.c | 31 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush_channels.c | 20 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 4 |
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", ""); |