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:
authorWilliam Reynish <billrey@me.com>2019-03-19 20:17:50 +0300
committerWilliam Reynish <billrey@me.com>2019-03-19 20:17:50 +0300
commit83fc8342d8271135d7ee0d0a380701cdfde3b20c (patch)
tree7fe1c0601ca7e651682244d24a3086e0493eda62
parentc590e8046671e2b8f2b4d3ce9d60780e20bf4438 (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.py176
-rw-r--r--release/scripts/startup/bl_ui/space_image.py145
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py346
-rw-r--r--source/blender/makesrna/intern/rna_brush.c35
-rw-r--r--source/blender/makesrna/intern/rna_scene.c17
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 ");
+
}