diff options
author | William Reynish <billrey@me.com> | 2019-03-19 20:17:50 +0300 |
---|---|---|
committer | William Reynish <billrey@me.com> | 2019-03-19 20:17:50 +0300 |
commit | 83fc8342d8271135d7ee0d0a380701cdfde3b20c (patch) | |
tree | 7fe1c0601ca7e651682244d24a3086e0493eda62 | |
parent | c590e8046671e2b8f2b4d3ce9d60780e20bf4438 (diff) |
UI: Re-organize Brush Properties
- Consolidate each brush section (Color, Palette, Gradient) and make them distinct
- Remove the lock icons and move these items into an Options sub-panel, together with other toggles
- They now have more descriptive names
- Use an enum for view vs scene brush unit
- Use Property Split layout and sub-panels in line with the rest of 2.8
- Rename Curve panel to Falloff
Reviewed by: campbellbarton, pablovazquez
Maniphest Tasks: D4529
Differential Revision: https://developer.blender.org/D4529
-rw-r--r-- | release/scripts/startup/bl_ui/properties_paint_common.py | 176 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_image.py | 145 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 346 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 35 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_scene.c | 17 |
5 files changed, 498 insertions, 221 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index ac63948d18a..913643f6d84 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -52,18 +52,18 @@ class UnifiedPaintPanel: flow = parent.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False) col = flow.column() - col.prop(ups, "use_unified_size", text="Size") + col.prop(ups, "use_unified_size", text="Unified Size") col = flow.column() - col.prop(ups, "use_unified_strength", text="Strength") + col.prop(ups, "use_unified_strength", text="Unified Strength") if context.weight_paint_object: col = flow.column() - col.prop(ups, "use_unified_weight", text="Weight") + col.prop(ups, "use_unified_weight", text="Unified Weight") elif context.vertex_paint_object or context.image_paint_object: col = flow.column() - col.prop(ups, "use_unified_color", text="Color") + col.prop(ups, "use_unified_color", text="Unified Color") else: col = flow.column() - col.prop(ups, "use_unified_color", text="Color") + col.prop(ups, "use_unified_color", text="Unified Color") @staticmethod def prop_unified_size(parent, context, brush, prop_name, *, icon='NONE', text=None, slider=False): @@ -114,109 +114,102 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal col = layout.column() if capabilities.has_color: - if brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'}: - if not brush.use_gradient: - panel.prop_unified_color_picker(col, context, brush, "color", value_slider=True) - - if settings.palette: - col.template_palette(settings, "palette", color=True) - - if brush.use_gradient: - col.label(text="Gradient Colors") - col.template_color_ramp(brush, "gradient", expand=True) - - if brush.image_tool == 'DRAW': - col.label(text="Background Color") - row = col.row(align=True) - panel.prop_unified_color(row, context, brush, "secondary_color", text="") - col.prop(brush, "gradient_stroke_mode", text="Mode") - if brush.gradient_stroke_mode in {'SPACING_REPEAT', 'SPACING_CLAMP'}: - col.prop(brush, "grad_spacing") - else: # if brush.image_tool == 'FILL': - col.prop(brush, "gradient_fill_mode") - else: - row = col.row(align=True) - panel.prop_unified_color(row, context, brush, "color", text="") - if brush.image_tool == 'FILL' and not projpaint: - col.prop(brush, "fill_threshold") - else: - panel.prop_unified_color(row, context, brush, "secondary_color", text="") - row.separator() - row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="") - else: + if brush.blend in {'ERASE_ALPHA', 'ADD_ALPHA'}: if brush.image_tool == 'FILL' and not projpaint: col.prop(brush, "fill_threshold") elif brush.image_tool == 'SOFTEN': - col = layout.column(align=True) col.row().prop(brush, "direction", expand=True) - col.separator() col.prop(brush, "sharp_threshold") if not projpaint: col.prop(brush, "blur_kernel_radius") - col.separator() col.prop(brush, "blur_mode") elif brush.image_tool == 'MASK': col.prop(brush, "weight", text="Mask Value", slider=True) elif brush.image_tool == 'CLONE': - col.separator() - if projpaint: - if settings.mode == 'MATERIAL': - col.prop(settings, "use_clone_layer", text="Clone from Paint Slot") - elif settings.mode == 'IMAGE': - col.prop(settings, "use_clone_layer", text="Clone from Image/UV Map") - - if settings.use_clone_layer: - ob = context.active_object - col = layout.column() - - if settings.mode == 'MATERIAL': - if len(ob.material_slots) > 1: - col.label(text="Materials") - col.template_list("MATERIAL_UL_matslots", "", - ob, "material_slots", - ob, "active_material_index", rows=2) - - mat = ob.active_material - if mat: - col.label(text="Source Clone Slot") - col.template_list("TEXTURE_UL_texpaintslots", "", - mat, "texture_paint_images", - mat, "paint_clone_slot", rows=2) - - elif settings.mode == 'IMAGE': - mesh = ob.data - - clone_text = mesh.uv_layer_clone.name if mesh.uv_layer_clone else "" - col.label(text="Source Clone Image") - col.template_ID(settings, "clone_image") - col.label(text="Source Clone UV Map") - col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False) - else: + if not projpaint: col.prop(brush, "clone_image", text="Image") col.prop(brush, "clone_alpha", text="Alpha") - col.separator() - if not panel.is_popover: brush_basic_texpaint_settings(col, context, brush) + +def brush_texpaint_common_clone(panel, context, layout, brush, settings, projpaint=False): + capabilities = brush.image_paint_capabilities + + ob = context.active_object + col = layout.column() + + if settings.mode == 'MATERIAL': + if len(ob.material_slots) > 1: + col.label(text="Materials") + col.template_list("MATERIAL_UL_matslots", "", + ob, "material_slots", + ob, "active_material_index", rows=2) + + mat = ob.active_material + if mat: + col.label(text="Source Clone Slot") + col.template_list("TEXTURE_UL_texpaintslots", "", + mat, "texture_paint_images", + mat, "paint_clone_slot", rows=2) + + elif settings.mode == 'IMAGE': + mesh = ob.data + + clone_text = mesh.uv_layer_clone.name if mesh.uv_layer_clone else "" + col.label(text="Source Clone Image") + col.template_ID(settings, "clone_image") + col.label(text="Source Clone UV Map") + col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False) + + +def brush_texpaint_common_color(panel, context, layout, brush, settings, projpaint=False): + capabilities = brush.image_paint_capabilities + + UnifiedPaintPanel.prop_unified_color_picker(layout, context, brush, "color", value_slider=True) + + row = layout.row(align=True) + UnifiedPaintPanel.prop_unified_color(row, context, brush, "color", text="") + UnifiedPaintPanel.prop_unified_color(row, context, brush, "secondary_color", text="") + row.separator() + row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="", emboss=False) + + +def brush_texpaint_common_gradient(panel, context, layout, brush, settings, projpaint=False): + capabilities = brush.image_paint_capabilities + + layout.template_color_ramp(brush, "gradient", expand=True) + + layout.use_property_split = True + + col = layout.column() + + if brush.image_tool == 'DRAW': + UnifiedPaintPanel.prop_unified_color(col, context, brush, "secondary_color", text="Background Color") + col.prop(brush, "gradient_stroke_mode", text="Mode") + if brush.gradient_stroke_mode in {'SPACING_REPEAT', 'SPACING_CLAMP'}: + col.prop(brush, "grad_spacing") + else: # if brush.image_tool == 'FILL': + col.prop(brush, "gradient_fill_mode") + + +def brush_texpaint_common_options(panel, context, layout, brush, settings, projpaint=False): + capabilities = brush.image_paint_capabilities + col = layout.column() - # use_accumulate if capabilities.has_accumulate: - col = layout.column(align=True) col.prop(brush, "use_accumulate") + if capabilities.has_space_attenuation: + col.prop(brush, "use_space_attenuation") + if projpaint: col.prop(brush, "use_alpha") - col.prop(brush, "use_gradient") - - col.separator() - col.template_ID(settings, "palette", new="palette.new") - # Used in both the View3D toolbar and texture properties def brush_texture_settings(layout, brush, sculpt): @@ -316,7 +309,6 @@ def brush_basic_wpaint_settings(layout, context, brush, *, compact=False): UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength") UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="") - layout.separator() layout.prop(brush, "blend", text="" if compact else "Blend") @@ -333,7 +325,6 @@ def brush_basic_vpaint_settings(layout, context, brush, *, compact=False): if capabilities.has_color: - layout.separator() layout.prop(brush, "blend", text="" if compact else "Blend") @@ -347,28 +338,25 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False): row = layout.row(align=True) - if capabilities.has_space_attenuation: - row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True) - UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength") UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="") if capabilities.has_color: - layout.separator() layout.prop(brush, "blend", text="" if compact else "Blend") def brush_basic_sculpt_settings(layout, context, brush, *, compact=False): tool_settings = context.tool_settings capabilities = brush.sculpt_capabilities + settings = tool_settings.gpencil_sculpt + tool = settings.sculpt_tool row = layout.row(align=True) - UnifiedPaintPanel.prop_unified_size(row, context, brush, "use_locked_size", text="") ups = tool_settings.unified_paint_settings if ( - (ups.use_unified_size and ups.use_locked_size) or - ((not ups.use_unified_size) and brush.use_locked_size) + (ups.use_unified_size and ups.use_locked_size == 'SCENE') or + ((not ups.use_unified_size) and brush.use_locked_size == 'SCENE') ): UnifiedPaintPanel.prop_unified_size(row, context, brush, "unprojected_radius", slider=True, text="Radius") else: @@ -377,20 +365,16 @@ def brush_basic_sculpt_settings(layout, context, brush, *, compact=False): UnifiedPaintPanel.prop_unified_size(row, context, brush, "use_pressure_size", text="") # strength, use_strength_pressure, and use_strength_attenuation - layout.separator() row = layout.row(align=True) - if capabilities.has_space_attenuation: - row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True) - UnifiedPaintPanel.prop_unified_strength(row, context, brush, "strength") if capabilities.has_strength_pressure: UnifiedPaintPanel.prop_unified_strength(row, context, brush, "use_pressure_strength", text="") # direction - layout.separator() - layout.row().prop(brush, "direction", expand=True, **({"text": ""} if compact else {})) + if capabilities.has_direction == False: + layout.row().prop(brush, "direction", expand=True, **({"text": ""} if compact else {})) def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=True): diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 7d8e4e7eb3e..2da618c66cd 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -28,6 +28,10 @@ from .properties_paint_common import ( UnifiedPaintPanel, brush_texture_settings, brush_texpaint_common, + brush_texpaint_common_color, + brush_texpaint_common_gradient, + brush_texpaint_common_clone, + brush_texpaint_common_options, brush_mask_texture_settings, ) from .properties_grease_pencil_common import ( @@ -842,6 +846,9 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + settings = context.tool_settings.image_paint brush = settings.brush @@ -852,6 +859,135 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel): brush_texpaint_common(self, context, layout, brush, settings) +class IMAGE_PT_paint_color(Panel, ImagePaintPanel): + bl_context = ".paint_common_2d" + bl_parent_id = "IMAGE_PT_paint" + bl_label = "Color Picker" + + @classmethod + def poll(self, context): + settings = context.tool_settings.image_paint + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color + + def draw(self, context): + layout = self.layout + settings = context.tool_settings.image_paint + brush = settings.brush + + layout.active = brush.use_gradient == False + + brush_texpaint_common_color(self, context, layout, brush, settings, True) + + +class IMAGE_PT_paint_swatches(Panel, ImagePaintPanel): + bl_context = ".paint_common_2d" + bl_parent_id = "IMAGE_PT_paint" + bl_label = "Color Palette" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = context.tool_settings.image_paint + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color + + def draw(self, context): + layout = self.layout + settings = context.tool_settings.image_paint + + layout.template_ID(settings, "palette", new="palette.new") + if settings.palette: + layout.template_palette(settings, "palette", color=True) + + +class IMAGE_PT_paint_gradient(Panel, ImagePaintPanel): + bl_context = ".paint_common_2d" + bl_parent_id = "IMAGE_PT_paint" + bl_label = "Gradient" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = context.tool_settings.image_paint + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color + + def draw_header(self, context): + settings = self.paint_settings(context) + brush = settings.brush + self.layout.prop(brush, "use_gradient", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = False + layout.use_property_decorate = False # No animation. + settings = context.tool_settings.image_paint + brush = settings.brush + + layout.active = brush.use_gradient + + brush_texpaint_common_gradient(self, context, layout, brush, settings, True) + + +class IMAGE_PT_paint_clone(Panel, ImagePaintPanel): + bl_context = ".paint_common_2d" + bl_parent_id = "IMAGE_PT_paint" + bl_label = "Clone from Image/UV Map" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = self.paint_settings(context) + brush = settings.brush + + return brush.image_tool == 'CLONE' + + def draw_header(self, context): + settings = context.tool_settings.image_paint + self.layout.prop(settings, "use_clone_layer", text="") + + def draw(self, context): + layout = self.layout + settings = context.tool_settings.image_paint + brush = settings.brush + + layout.active = settings.use_clone_layer + + brush_texpaint_common_clone(self, context, layout, brush, settings, True) + + +class IMAGE_PT_paint_options(Panel, ImagePaintPanel): + bl_context = ".paint_common_2d" + bl_parent_id = "IMAGE_PT_paint" + bl_label = "Options" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = context.tool_settings.image_paint + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color + + def draw(self, context): + layout = self.layout + settings = context.tool_settings.image_paint + brush = settings.brush + + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + brush_texpaint_common_options(self, context, layout, brush, settings, True) + + class IMAGE_PT_tools_brush_display(BrushButtonsPanel, Panel): bl_label = "Display" bl_context = ".paint_common_2d" @@ -1022,7 +1158,7 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel): class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel): - bl_label = "Curve" + bl_label = "Falloff" bl_context = ".paint_common_2d" bl_options = {'DEFAULT_CLOSED'} bl_category = "Tools" @@ -1351,11 +1487,16 @@ classes = ( IMAGE_PT_view_display_uv_edit_overlays, IMAGE_PT_view_display_uv_edit_overlays_advanced, IMAGE_PT_paint, - IMAGE_PT_tools_brush_display, + IMAGE_PT_paint_color, + IMAGE_PT_paint_swatches, + IMAGE_PT_paint_gradient, + IMAGE_PT_paint_clone, + IMAGE_PT_paint_options, IMAGE_PT_tools_brush_texture, IMAGE_PT_tools_mask_texture, IMAGE_PT_paint_stroke, IMAGE_PT_paint_curve, + IMAGE_PT_tools_brush_display, IMAGE_PT_tools_imagepaint_symmetry, IMAGE_PT_tools_brush_appearance, IMAGE_PT_uv_sculpt, diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 3c90872e3c4..b4bffadf489 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -29,6 +29,10 @@ from .properties_paint_common import ( UnifiedPaintPanel, brush_mask_texture_settings, brush_texpaint_common, + brush_texpaint_common_color, + brush_texpaint_common_gradient, + brush_texpaint_common_clone, + brush_texpaint_common_options, brush_texture_settings, ) from bl_ui.utils import PresetPanel @@ -273,12 +277,16 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + tool_settings = context.tool_settings settings = self.paint_settings(context) brush = settings.brush - col = layout.split().column() - col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8) + if not self.is_popover: + col = layout.split().column() + col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8) # Sculpt Mode # if context.sculpt_object and brush: @@ -290,8 +298,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): col = layout.column() - col.separator() - if not self.is_popover: brush_basic_sculpt_settings(col, context, brush) @@ -299,47 +305,32 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): if (capabilities.has_topology_rake and context.sculpt_object.use_dynamic_topology_sculpting ): - col.separator() row = col.row() row.prop(brush, "topology_rake_factor", slider=True) # auto_smooth_factor and use_inverse_smooth_pressure if capabilities.has_auto_smooth: - col.separator() - row = col.row(align=True) row.prop(brush, "auto_smooth_factor", slider=True) row.prop(brush, "use_inverse_smooth_pressure", toggle=True, text="") # normal_weight if capabilities.has_normal_weight: - col.separator() row = col.row(align=True) row.prop(brush, "normal_weight", slider=True) # crease_pinch_factor if capabilities.has_pinch_factor: - col.separator() row = col.row(align=True) row.prop(brush, "crease_pinch_factor", slider=True, text="Pinch") # rake_factor if capabilities.has_rake_factor: - col.separator() row = col.row(align=True) row.prop(brush, "rake_factor", slider=True) - # use_original_normal and sculpt_plane - if capabilities.has_sculpt_plane: - col.separator() - row = col.row(align=True) - - row.prop(brush, "use_original_normal", toggle=True, icon_only=True) - - row.prop(brush, "sculpt_plane", text="") - if brush.sculpt_tool == 'MASK': - col.prop(brush, "mask_tool", text="") + col.prop(brush, "mask_tool") # plane_offset, use_offset_pressure, use_plane_trim, plane_trim if capabilities.has_plane_offset: @@ -350,7 +341,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): col.separator() row = col.row() - row.prop(brush, "use_plane_trim", text="Trim") + row.prop(brush, "use_plane_trim", text="Plane Trim") row = col.row() row.active = brush.use_plane_trim row.prop(brush, "plane_trim", slider=True, text="Distance") @@ -360,21 +351,8 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): row = col.row() row.prop(brush, "height", slider=True, text="Height") - # use_frontface - col.separator() - col.prop(brush, "use_frontface", text="Front Faces Only") - col.prop(brush, "use_projected") - - # use_accumulate - if capabilities.has_accumulate: - col.separator() - - col.prop(brush, "use_accumulate") - # use_persistent, set_persistent_base if capabilities.has_persistence: - col.separator() - ob = context.sculpt_object do_persistent = True @@ -404,61 +382,177 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): if not self.is_popover: brush_basic_wpaint_settings(col, context, brush) - if brush.weight_tool != 'SMEAR': - col.prop(brush, "use_accumulate") - col.separator() - - col.prop(brush, "use_frontface", text="Front Faces Only") - row = col.row() - row.prop(brush, "use_frontface_falloff", text="Falloff Angle") - sub = row.row() - sub.active = brush.use_frontface_falloff - sub.prop(brush, "falloff_angle", text="") - - col.prop(brush, "use_projected") - - col = layout.column() - col.prop(tool_settings, "use_auto_normalize", text="Auto Normalize") - col.prop(tool_settings, "use_multipaint", text="Multi-Paint") - # Vertex Paint Mode # elif context.vertex_paint_object and brush: from .properties_paint_common import ( brush_basic_vpaint_settings, ) - col = layout.column() - self.prop_unified_color_picker(col, context, brush, "color", value_slider=True) - if settings.palette: - col.template_palette(settings, "palette", color=True) - row = col.row(align=True) - self.prop_unified_color(row, context, brush, "color", text="") - self.prop_unified_color(row, context, brush, "secondary_color", text="") - row.separator() - row.operator("paint.brush_colors_flip", icon='FILE_REFRESH', text="") - - col.separator() - if not self.is_popover: brush_basic_vpaint_settings(col, context, brush) - col.prop(brush, "use_alpha") - if brush.vertex_tool != 'SMEAR': - col.prop(brush, "use_accumulate") - col.separator() + + +class VIEW3D_PT_tools_brush_color(Panel, View3DPaintPanel): + bl_context = ".paint_common" # dot on purpose (access from topbar) + bl_parent_id = "VIEW3D_PT_tools_brush" + bl_label = "Color Picker" + + @classmethod + def poll(self, context): + settings = self.paint_settings(context) + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color and (context.image_paint_object or context.vertex_paint_object) + + def draw(self, context): + layout = self.layout + settings = self.paint_settings(context) + brush = settings.brush + + layout.active = brush.use_gradient == False + + brush_texpaint_common_color(self, context, layout, brush, settings, True) + + +class VIEW3D_PT_tools_brush_swatches(Panel, View3DPaintPanel): + bl_context = ".paint_common" # dot on purpose (access from topbar) + bl_parent_id = "VIEW3D_PT_tools_brush" + bl_label = "Color Palette" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = self.paint_settings(context) + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color and (context.image_paint_object or context.vertex_paint_object) + + def draw(self, context): + layout = self.layout + settings = self.paint_settings(context) + + layout.template_ID(settings, "palette", new="palette.new") + if settings.palette: + layout.template_palette(settings, "palette", color=True) + + +class VIEW3D_PT_tools_brush_gradient(Panel, View3DPaintPanel): + bl_context = ".paint_common" # dot on purpose (access from topbar) + bl_parent_id = "VIEW3D_PT_tools_brush" + bl_label = "Gradient" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = self.paint_settings(context) + brush = settings.brush + capabilities = brush.image_paint_capabilities + + return capabilities.has_color and context.image_paint_object + + def draw_header(self, context): + settings = self.paint_settings(context) + brush = settings.brush + self.layout.prop(brush, "use_gradient", text="") + + def draw(self, context): + layout = self.layout + layout.use_property_split = False + layout.use_property_decorate = False # No animation. + settings = self.paint_settings(context) + brush = settings.brush + + layout.active = brush.use_gradient + + brush_texpaint_common_gradient(self, context, layout, brush, settings, True) + + +class VIEW3D_PT_tools_brush_clone(Panel, View3DPaintPanel): + bl_context = ".paint_common" # dot on purpose (access from topbar) + bl_parent_id = "VIEW3D_PT_tools_brush" + bl_label = "Clone from Paint Slot" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(self, context): + settings = self.paint_settings(context) + brush = settings.brush + + return brush.image_tool == 'CLONE' + + def draw_header(self, context): + settings = self.paint_settings(context) + self.layout.prop(settings, "use_clone_layer", text="") + + def draw(self, context): + layout = self.layout + settings = self.paint_settings(context) + brush = settings.brush + + layout.active = settings.use_clone_layer + + brush_texpaint_common_clone(self, context, layout, brush, settings, True) + + +class VIEW3D_PT_tools_brush_options(Panel, View3DPaintPanel): + bl_context = ".paint_common" # dot on purpose (access from topbar) + bl_parent_id = "VIEW3D_PT_tools_brush" + bl_label = "Options" + bl_options = {'DEFAULT_CLOSED'} + + def draw(self, context): + layout = self.layout + tool_settings = context.tool_settings + settings = self.paint_settings(context) + brush = settings.brush + capabilities = brush.sculpt_capabilities + + layout.use_property_split = True + layout.use_property_decorate = False # No animation. + + col = layout.column() + + if context.image_paint_object and brush: + brush_texpaint_common_options(self, context, layout, brush, settings, True) + + elif context.sculpt_object and brush: + if capabilities.has_accumulate: + col.prop(brush, "use_accumulate", text="Airbrush") + + UnifiedPaintPanel.prop_unified_size(col, context, brush, "use_locked_size") + + if capabilities.has_sculpt_plane: + col.prop(brush, "sculpt_plane") + col.prop(brush, "use_original_normal") + + if capabilities.has_space_attenuation: + col.prop(brush, "use_space_attenuation") col.prop(brush, "use_frontface", text="Front Faces Only") - row = col.row() - row.prop(brush, "use_frontface_falloff", text="Falloff Angle") - sub = row.row() - sub.active = brush.use_frontface_falloff - sub.prop(brush, "falloff_angle", text="") + col.prop(brush, "use_projected") + + elif context.weight_paint_object and brush: + + if brush.weight_tool != 'SMEAR': + col.prop(brush, "use_accumulate") + col.prop(brush, "use_frontface", text="Front Faces Only") col.prop(brush, "use_projected") + col.prop(tool_settings, "use_auto_normalize", text="Auto Normalize") + col.prop(tool_settings, "use_multipaint", text="Multi-Paint") - col.separator() - col.template_ID(settings, "palette", new="palette.new") + elif context.vertex_paint_object and brush: + + if brush.vertex_tool != 'SMEAR': + col.prop(brush, "use_accumulate") + + col.prop(brush, "use_alpha") + col.prop(brush, "use_frontface", text="Front Faces Only") + col.prop(brush, "use_projected") class TEXTURE_UL_texpaintslots(UIList): @@ -826,9 +920,9 @@ class VIEW3D_PT_tools_brush_stroke_smooth_stroke(Panel, View3DPaintPanel): # TODO, move to space_view3d.py -class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): +class VIEW3D_PT_tools_brush_falloff(Panel, View3DPaintPanel): bl_context = ".paint_common" # dot on purpose (access from topbar) - bl_label = "Curve" + bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} @classmethod @@ -838,9 +932,7 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): def draw(self, context): layout = self.layout - settings = self.paint_settings(context) - brush = settings.brush layout.template_curve_mapping(brush, "curve", brush=True) @@ -855,6 +947,64 @@ class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' +class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel): + bl_context = ".imagepaint" # dot on purpose (access from topbar) + bl_label = "Frontface Falloff" + bl_parent_id = "VIEW3D_PT_tools_brush_falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return (context.weight_paint_object or context.vertex_paint_object) + + def draw_header(self, context): + settings = self.paint_settings(context) + brush = settings.brush + + self.layout.prop(brush, "use_frontface_falloff", text="") + + def draw(self, context): + settings = self.paint_settings(context) + brush = settings.brush + + layout = self.layout + + layout.use_property_split = True + layout.use_property_decorate = False + + layout.active = brush.use_frontface_falloff + layout.prop(brush, "falloff_angle", text="Angle") + + +class VIEW3D_PT_tools_brush_falloff_normal(View3DPaintPanel, Panel): + bl_context = ".imagepaint" # dot on purpose (access from topbar) + bl_label = "Normal Falloff" + bl_parent_id = "VIEW3D_PT_tools_brush_falloff" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return context.image_paint_object + + def draw_header(self, context): + tool_settings = context.tool_settings + ipaint = tool_settings.image_paint + + self.layout.prop(ipaint, "use_normal_falloff", text="") + + def draw(self, context): + tool_settings = context.tool_settings + ipaint = tool_settings.image_paint + + layout = self.layout + + layout.use_property_split = True + layout.use_property_decorate = False + + layout.active = ipaint.use_normal_falloff + layout.prop(ipaint, "normal_angle", text="Angle") + + # TODO, move to space_view3d.py class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel): bl_context = ".sculpt_mode" # dot on purpose (access from topbar) @@ -1173,6 +1323,7 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel): class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): bl_context = ".weightpaint" bl_label = "Options" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout @@ -1200,9 +1351,11 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): class VIEW3D_PT_tools_vertexpaint(Panel, View3DPaintPanel): bl_context = ".vertexpaint" # dot on purpose (access from topbar) bl_label = "Options" + bl_options = {'DEFAULT_CLOSED'} def draw(self, context): layout = self.layout + settings = self.paint_settings(context) col = layout.column() @@ -1310,31 +1463,6 @@ class VIEW3D_PT_tools_projectpaint(View3DPaintPanel, Panel): col.prop(ipaint, "use_backface_culling", text="Backface Culling") -class VIEW3D_PT_tools_projectpaint_normal(View3DPaintPanel, Panel): - bl_context = ".imagepaint" # dot on purpose (access from topbar) - bl_label = "Normal" - bl_parent_id = "VIEW3D_PT_tools_projectpaint" - bl_options = {'DEFAULT_CLOSED'} - - def draw_header(self, context): - tool_settings = context.tool_settings - ipaint = tool_settings.image_paint - - self.layout.prop(ipaint, "use_normal_falloff", text="") - - def draw(self, context): - layout = self.layout - - layout.use_property_split = True - layout.use_property_decorate = False - - tool_settings = context.tool_settings - ipaint = tool_settings.image_paint - - layout.active = ipaint.use_normal_falloff - layout.prop(ipaint, "normal_angle", text="Angle") - - class VIEW3D_PT_tools_projectpaint_unified(Panel, View3DPaintPanel): bl_context = ".imagepaint" # dot on purpose (access from topbar) bl_parent_id = "VIEW3D_PT_tools_projectpaint" @@ -1879,15 +2007,22 @@ classes = ( VIEW3D_PT_tools_posemode_options, VIEW3D_PT_slots_projectpaint, VIEW3D_PT_tools_brush, + VIEW3D_PT_tools_brush_color, + VIEW3D_PT_tools_brush_swatches, + VIEW3D_PT_tools_brush_gradient, + VIEW3D_PT_tools_brush_clone, + VIEW3D_PT_tools_brush_options, TEXTURE_UL_texpaintslots, VIEW3D_MT_tools_projectpaint_uvlayer, VIEW3D_PT_stencil_projectpaint, - VIEW3D_PT_tools_brush_display, VIEW3D_PT_tools_brush_texture, VIEW3D_PT_tools_mask_texture, VIEW3D_PT_tools_brush_stroke, VIEW3D_PT_tools_brush_stroke_smooth_stroke, - VIEW3D_PT_tools_brush_curve, + VIEW3D_PT_tools_brush_falloff, + VIEW3D_PT_tools_brush_falloff_frontface, + VIEW3D_PT_tools_brush_falloff_normal, + VIEW3D_PT_tools_brush_display, VIEW3D_PT_sculpt_dyntopo, VIEW3D_PT_sculpt_dyntopo_remesh, VIEW3D_PT_sculpt_options, @@ -1904,7 +2039,6 @@ classes = ( VIEW3D_PT_tools_imagepaint_external, VIEW3D_PT_tools_imagepaint_symmetry, VIEW3D_PT_tools_projectpaint, - VIEW3D_PT_tools_projectpaint_normal, VIEW3D_PT_tools_projectpaint_cavity, VIEW3D_MT_tools_projectpaint_stencil, VIEW3D_PT_tools_projectpaint_unified, diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index c07e9523148..775a76976a0 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -346,6 +346,16 @@ static bool rna_TextureCapabilities_has_texture_angle_get(PointerRNA *ptr) return mtex->brush_map_mode != MTEX_MAP_MODE_3D; } +static bool rna_BrushCapabilitiesSculpt_has_direction_get(PointerRNA *ptr) +{ + Brush *br = (Brush *)ptr->data; + return !ELEM(br->sculpt_tool, SCULPT_TOOL_DRAW, SCULPT_TOOL_CLAY, + SCULPT_TOOL_CLAY_STRIPS, SCULPT_TOOL_LAYER, SCULPT_TOOL_INFLATE, + SCULPT_TOOL_BLOB, SCULPT_TOOL_CREASE, SCULPT_TOOL_FLATTEN, + SCULPT_TOOL_FILL, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_CLAY, + SCULPT_TOOL_PINCH, SCULPT_TOOL_MASK); +} + static bool rna_BrushCapabilitiesSculpt_has_gravity_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; @@ -880,6 +890,7 @@ static void rna_def_sculpt_capabilities(BlenderRNA *brna) SCULPT_TOOL_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke"); SCULPT_TOOL_CAPABILITY(has_space_attenuation, "Has Space Attenuation"); SCULPT_TOOL_CAPABILITY(has_strength_pressure, "Has Strength Pressure"); + SCULPT_TOOL_CAPABILITY(has_direction, "Has Direction"); SCULPT_TOOL_CAPABILITY(has_gravity, "Has Gravity"); #undef SCULPT_CAPABILITY @@ -1423,6 +1434,12 @@ static void rna_def_brush(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem brush_size_unit_items[] = { + {0, "VIEW", 0, "View", "Measure brush size relateve to the view"}, + {BRUSH_LOCK_SIZE, "SCENE", 0, "Scene", "Measure brush size relateve to the scene"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "Brush", "ID"); RNA_def_struct_ui_text(srna, "Brush", "Brush data-block for storing brush settings for painting and sculpting"); RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA); @@ -1723,7 +1740,6 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "use_original_normal", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ORIGINAL_NORMAL); - RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true); RNA_def_property_ui_text(prop, "Original Normal", "When locked keep using normal of surface where stroke was initiated"); RNA_def_property_update(prop, 0, "rna_Brush_update"); @@ -1829,13 +1845,12 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "use_accumulate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_ACCUMULATE); - RNA_def_property_ui_text(prop, "Accumulate", "Accumulate stroke daubs on top of each other"); + RNA_def_property_ui_text(prop, "Airbrush", "Accumulate stroke daubs on top of each other"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_space_attenuation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE_ATTEN); - RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true); - RNA_def_property_ui_text(prop, "Use Automatic Strength Adjustment", + RNA_def_property_ui_text(prop, "Adjust Strength for Spacing", "Automatically adjust strength to give consistent results for different spacings"); RNA_def_property_update(prop, 0, "rna_Brush_update"); @@ -1846,12 +1861,10 @@ static void rna_def_brush(BlenderRNA *brna) "Space daubs according to surface orientation instead of screen space"); RNA_def_property_update(prop, 0, "rna_Brush_update"); - prop = RNA_def_property(srna, "use_locked_size", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_LOCK_SIZE); - RNA_def_property_ui_text(prop, "Use Blender Units", - "When locked brush stays same size relative to object; when unlocked brush size is " - "given in pixels"); - RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true); + prop = RNA_def_property(srna, "use_locked_size", PROP_ENUM, PROP_NONE); /* as an enum */ + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, brush_size_unit_items); + RNA_def_property_ui_text(prop, "Radius Unit", "Measure brush size relative to the view or the scene"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_edge_to_edge", PROP_BOOLEAN, PROP_NONE); @@ -1867,7 +1880,7 @@ static void rna_def_brush(BlenderRNA *brna) /* only for projection paint & vertex paint, TODO, other paint modes */ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_LOCK_ALPHA); - RNA_def_property_ui_text(prop, "Alpha", "When this is disabled, lock alpha while painting"); + RNA_def_property_ui_text(prop, "Affect Alpha", "When this is disabled, lock alpha while painting"); RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 080b29fa7a9..6b2156dcef9 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2931,6 +2931,12 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static const EnumPropertyItem brush_size_unit_items[] = { + {0, "VIEW", 0, "View", "Measure brush size relateve to the view"}, + {UNIFIED_PAINT_BRUSH_LOCK_SIZE, "SCENE", 0, "Scene", "Measure brush size relateve to the scene"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "UnifiedPaintSettings", NULL); RNA_def_struct_path_func(srna, "rna_UnifiedPaintSettings_path"); RNA_def_struct_ui_text(srna, "Unified Paint Settings", "Overrides for some of the active brush's settings"); @@ -3016,12 +3022,11 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Strength Pressure", "Enable tablet pressure sensitivity for strength"); - prop = RNA_def_property(srna, "use_locked_size", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_BRUSH_LOCK_SIZE); - RNA_def_property_ui_text(prop, "Use Blender Units", - "When locked brush stays same size relative to object; " - "when unlocked brush size is given in pixels"); - RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true); + prop = RNA_def_property(srna, "use_locked_size", PROP_ENUM, PROP_NONE); /* as an enum */ + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, brush_size_unit_items); + RNA_def_property_ui_text(prop, "Radius Unit", "Measure brush size relative to the view or the scene "); + } |