UV Sculpt: improve tool-system integration
authorCampbell Barton <ideasman42@gmail.com>
Wed, 1 May 2019 08:10:34 +0000 (18:10 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 1 May 2019 10:32:38 +0000 (20:32 +1000)
In 2.7x UV sculpt was a kind of sub-mode
(a toggle with it's own key-map & drawing code).

Move this to an operator that uses the tool-system,
this simplifies internal logic, especially brush selection
which now matches sculpt and other paint modes.

- Remove toggle used to enable uv sculpt.
- Expose the brush, which was already used but there was no way to
  select different brushes.
- Make UV sculpt use paint paint tool slots
  (using brushes how all other paint mode currently do).
- Move UV Sculpt keymap to the tools keymap.
- Remove Q to toggle UV sculpt mode,
  S/P/G keys to switch tools.

28 files changed:
doc/python_api/sphinx_doc_gen.py
release/scripts/presets/keyconfig/keymap_data/blender_default.py
release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
release/scripts/startup/bl_ui/space_image.py
release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
release/scripts/startup/bl_ui/space_view3d.py
source/blender/blenkernel/BKE_paint.h
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/paint_toolslots.c
source/blender/blenloader/intern/versioning_defaults.c
source/blender/editors/include/ED_image.h
source/blender/editors/include/ED_uvedit.h
source/blender/editors/object/object_edit.c
source/blender/editors/screen/screen_context.c
source/blender/editors/sculpt_paint/paint_intern.h
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/sculpt_paint/sculpt_uv.c
source/blender/editors/space_image/space_image.c
source/blender/editors/uvedit/uvedit_draw.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/makesdna/DNA_brush_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_brush.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/windowmanager/intern/wm_keymap_utils.c
source/blender/windowmanager/intern/wm_toolsystem.c

index 0d34392..f8b3f0c 100644 (file)
@@ -1054,7 +1054,6 @@ context_type_map = {
     "texture_slot": ("MaterialTextureSlot", False),
     "texture_user": ("ID", False),
     "texture_user_property": ("Property", False),
-    "uv_sculpt_object": ("Object", False),
     "vertex_paint_object": ("Object", False),
     "view_layer": ("ViewLayer", False),
     "visible_bases": ("ObjectBase", True),
index 9a4ad19..844e5d3 100644 (file)
@@ -863,8 +863,6 @@ def km_uv_editor(params):
             ("uv.minimize_stretch", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
             ("uv.pack_islands", {"type": 'P', "value": 'PRESS', "ctrl": True}, None),
             ("uv.average_islands_scale", {"type": 'A', "value": 'PRESS', "ctrl": True}, None),
-            ("wm.context_toggle", {"type": 'Q', "value": 'PRESS'},
-             {"properties": [("data_path", 'tool_settings.use_uv_sculpt')]}),
         ])
 
     if params.select_mouse == 'LEFTMOUSE' and not params.legacy:
@@ -877,39 +875,6 @@ def km_uv_editor(params):
     return keymap
 
 
-def km_uv_sculpt(_params):
-    items = []
-    keymap = (
-        "UV Sculpt",
-        {"space_type": 'EMPTY', "region_type": 'WINDOW'},
-        {"items": items},
-    )
-
-    items.extend([
-        ("wm.context_toggle", {"type": 'Q', "value": 'PRESS'},
-         {"properties": [("data_path", 'tool_settings.use_uv_sculpt')]}),
-        ("sculpt.uv_sculpt_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'},
-         {"properties": [("mode", 'NORMAL')]}),
-        ("sculpt.uv_sculpt_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
-         {"properties": [("mode", 'INVERT')]}),
-        ("sculpt.uv_sculpt_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
-         {"properties": [("mode", 'RELAX')]}),
-        ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'},
-         {"properties": [("scalar", 0.9)]}),
-        ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'},
-         {"properties": [("scalar", 1.0 / 0.9)]}),
-        *_template_paint_radial_control("uv_sculpt"),
-        ("brush.uv_sculpt_tool_set", {"type": 'S', "value": 'PRESS'},
-         {"properties": [("tool", 'RELAX')]}),
-        ("brush.uv_sculpt_tool_set", {"type": 'P', "value": 'PRESS'},
-         {"properties": [("tool", 'PINCH')]}),
-        ("brush.uv_sculpt_tool_set", {"type": 'G', "value": 'PRESS'},
-         {"properties": [("tool", 'GRAB')]}),
-    ])
-
-    return keymap
-
-
 # 3D View: all regions.
 def km_view3d_generic(_params):
     items = []
@@ -5277,6 +5242,25 @@ def km_image_editor_tool_uv_select_lasso(params):
     )
 
 
+def km_image_editor_tool_uv_sculpt_stroke(params):
+    return (
+        "Image Editor Tool: Uv, Sculpt Stroke",
+        {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
+        {"items": [
+            ("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS'}, None),
+            ("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True},
+             {"properties": [("mode", 'INVERT')]}),
+            ("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS', "shift": True},
+             {"properties": [("mode", 'RELAX')]}),
+            ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'},
+             {"properties": [("scalar", 0.9)]}),
+            ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'},
+             {"properties": [("scalar", 1.0 / 0.9)]}),
+            *_template_paint_radial_control("uv_sculpt"),
+        ]},
+    )
+
+
 def km_node_editor_tool_select(params):
     return (
         "Node Tool: Select",
@@ -6117,7 +6101,6 @@ def generate_keymaps(params=None):
         # Editors.
         km_outliner(params),
         km_uv_editor(params),
-        km_uv_sculpt(params),
         km_view3d_generic(params),
         km_view3d(params),
         km_mask_editing(params),
@@ -6245,6 +6228,7 @@ def generate_keymaps(params=None):
         km_image_editor_tool_uv_select_box(params),
         km_image_editor_tool_uv_select_circle(params),
         km_image_editor_tool_uv_select_lasso(params),
+        km_image_editor_tool_uv_sculpt_stroke(params),
         km_node_editor_tool_select(params),
         km_node_editor_tool_select_box(params),
         km_node_editor_tool_select_lasso(params),
index 0ea229a..2e67c63 100644 (file)
@@ -546,38 +546,6 @@ def km_uv_editor(params):
     return keymap
 
 
-def km_uv_sculpt(params):
-    items = []
-    keymap = (
-        "UV Sculpt",
-        {"space_type": 'EMPTY', "region_type": 'WINDOW'},
-        {"items": items},
-    )
-
-    items.extend([
-        ("wm.context_toggle", {"type": 'Q', "value": 'PRESS'},
-         {"properties": [("data_path", 'tool_settings.use_uv_sculpt')]}),
-        ("sculpt.uv_sculpt_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'},
-         {"properties": [("mode", 'NORMAL')]}),
-        ("sculpt.uv_sculpt_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
-         {"properties": [("mode", 'INVERT')]}),
-        ("sculpt.uv_sculpt_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
-         {"properties": [("mode", 'RELAX')]}),
-        ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'},
-         {"properties": [("scalar", 0.9)]}),
-        ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'},
-         {"properties": [("scalar", 1.0 / 0.9)]}),
-        *_template_paint_radial_control("uv_sculpt"),
-        ("brush.uv_sculpt_tool_set", {"type": 'S', "value": 'PRESS'},
-         {"properties": [("tool", 'RELAX')]}),
-        ("brush.uv_sculpt_tool_set", {"type": 'P', "value": 'PRESS'},
-         {"properties": [("tool", 'PINCH')]}),
-        ("brush.uv_sculpt_tool_set", {"type": 'G', "value": 'PRESS'},
-         {"properties": [("tool", 'GRAB')]}),
-    ])
-
-    return keymap
-
 # 3D View: all regions.
 def km_view3d_generic(_params):
     items = []
@@ -3582,7 +3550,6 @@ def generate_keymaps(params=None):
         # Editors.
         km_outliner(params),
         km_uv_editor(params),
-        km_uv_sculpt(params),
         km_view3d_generic(params),
         km_view3d(params),
         km_mask_editing(params),
index 466ba40..b27895f 100644 (file)
@@ -364,10 +364,6 @@ class IMAGE_MT_uvs(Menu):
 
         layout.separator()
 
-        layout.prop(tool_settings, "use_uv_sculpt")
-
-        layout.separator()
-
         layout.prop(uv, "use_live_unwrap")
         layout.operator("uv.unwrap")
 
@@ -555,8 +551,9 @@ class IMAGE_HT_tool_header(Header):
         if tool_mode == 'PAINT':
             if (tool is not None) and tool.has_datablock:
                 layout.popover_group(space_type='IMAGE_EDITOR', region_type='UI', context=".paint_common_2d", category="")
-        elif context.uv_sculpt_object is not None:
-            layout.popover_group(space_type='IMAGE_EDITOR', region_type='UI', context=".uv_sculpt", category="")
+        elif tool_mode == 'UV':
+            if (tool is not None) and tool.has_datablock:
+                layout.popover_group(space_type='IMAGE_EDITOR', region_type='UI', context=".uv_sculpt", category="")
 
     def draw_mode_settings(self, context):
         layout = self.layout
@@ -573,10 +570,10 @@ class IMAGE_HT_tool_header(Header):
 
 class _draw_tool_settings_context_mode:
     @staticmethod
-    def VIEW(context, layout, _tool):
-        tool_settings = context.tool_settings
-        if tool_settings.use_uv_sculpt:
+    def UV(context, layout, tool):
+        if tool and tool.has_datablock:
             if context.mode == 'EDIT_MESH':
+                tool_settings = context.tool_settings
                 uv_sculpt = tool_settings.uv_sculpt
                 brush = uv_sculpt.brush
                 if brush:
@@ -1378,54 +1375,33 @@ class IMAGE_PT_tools_imagepaint_symmetry(BrushButtonsPanel, Panel):
         row.prop(ipaint, "tile_y", text="Y", toggle=True)
 
 
-class IMAGE_PT_uv_sculpt_curve(Panel):
+class IMAGE_PT_uv_sculpt_brush(Panel):
     bl_space_type = 'IMAGE_EDITOR'
     bl_region_type = 'UI'
     bl_context = ".uv_sculpt"  # dot on purpose (access from topbar)
     bl_category = "Tool"
-    bl_label = "UV Sculpt Curve"
-    bl_options = {'DEFAULT_CLOSED'}
+    bl_label = "Brush"
 
     @classmethod
     def poll(cls, context):
-        return (context.uv_sculpt_object is not None)
+        sima = context.space_data
+        # TODO(campbell): nicer way to check if we're in uv sculpt mode.
+        if sima and sima.show_uvedit:
+            from .space_toolsystem_common import ToolSelectPanelHelper
+            tool = ToolSelectPanelHelper.tool_active_from_context(context)
+            if tool.has_datablock:
+                return True
+        return False
 
     def draw(self, context):
+        from .properties_paint_common import UnifiedPaintPanel
         layout = self.layout
 
         tool_settings = context.tool_settings
         uvsculpt = tool_settings.uv_sculpt
-        brush = uvsculpt.brush
-
-        if brush is not None:
-            layout.template_curve_mapping(brush, "curve")
 
-            row = layout.row(align=True)
-            row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
-            row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
-            row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
-            row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
-            row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE'
-            row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
-
-
-class IMAGE_PT_uv_sculpt(Panel):
-    bl_space_type = 'IMAGE_EDITOR'
-    bl_region_type = 'UI'
-    bl_context = ".uv_sculpt"  # dot on purpose (access from topbar)
-    bl_category = "Tool"
-    bl_label = "UV Sculpt"
-
-    @classmethod
-    def poll(cls, context):
-        return (context.uv_sculpt_object is not None)
-
-    def draw(self, context):
-        from .properties_paint_common import UnifiedPaintPanel
-        layout = self.layout
+        layout.template_ID(uvsculpt, "brush")
 
-        tool_settings = context.tool_settings
-        uvsculpt = tool_settings.uv_sculpt
         brush = uvsculpt.brush
 
         if not self.is_popover:
@@ -1444,13 +1420,43 @@ class IMAGE_PT_uv_sculpt(Panel):
         col.prop(tool_settings, "uv_sculpt_lock_borders")
         col.prop(tool_settings, "uv_sculpt_all_islands")
 
-        col.prop(tool_settings, "uv_sculpt_tool")
-        if tool_settings.uv_sculpt_tool == 'RELAX':
-            col.prop(tool_settings, "uv_relax_method")
+        if brush:
+            if brush.uv_sculpt_tool == 'RELAX':
+                col.prop(tool_settings, "uv_relax_method")
 
         col.prop(uvsculpt, "show_brush")
 
 
+class IMAGE_PT_uv_sculpt_curve(Panel):
+    bl_space_type = 'IMAGE_EDITOR'
+    bl_region_type = 'UI'
+    bl_context = ".uv_sculpt"  # dot on purpose (access from topbar)
+    bl_category = "Tool"
+    bl_label = "Falloff"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    poll = IMAGE_PT_uv_sculpt_brush.poll
+
+    def draw(self, context):
+        layout = self.layout
+
+        tool_settings = context.tool_settings
+        uvsculpt = tool_settings.uv_sculpt
+        brush = uvsculpt.brush
+
+        if brush is not None:
+            layout.template_curve_mapping(brush, "curve")
+
+            row = layout.row(align=True)
+            row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH'
+            row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND'
+            row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT'
+            row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP'
+            row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE'
+            row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX'
+
+
+
 class ImageScopesPanel:
     @classmethod
     def poll(cls, context):
@@ -1646,7 +1652,7 @@ classes = (
     IMAGE_PT_tools_brush_display_show_brush,
     IMAGE_PT_tools_brush_display_custom_icon,
     IMAGE_PT_tools_imagepaint_symmetry,
-    IMAGE_PT_uv_sculpt,
+    IMAGE_PT_uv_sculpt_brush,
     IMAGE_PT_uv_sculpt_curve,
     IMAGE_PT_view_histogram,
     IMAGE_PT_view_waveform,
index edde8f5..dee2fa3 100644 (file)
@@ -1171,12 +1171,33 @@ class _defs_image_uv_sculpt:
 
     @staticmethod
     def generate_from_brushes(context):
+        def draw_cursor(context, _tool, xy):
+            from gpu_extras.presets import draw_circle_2d
+            tool_settings = context.tool_settings
+            uv_sculpt = tool_settings.uv_sculpt
+            if not uv_sculpt.show_brush:
+                return
+            ups = tool_settings.unified_paint_settings
+            if ups.use_unified_size:
+                radius = ups.size
+            else:
+                brush = tool_settings.uv_sculpt.brush
+                if brush is None:
+                    return
+                radius = brush.size
+            draw_circle_2d(xy, (1.0,) * 4, radius, 32)
+
         return generate_from_enum_ex(
             context,
             idname_prefix="builtin_brush.",
             icon_prefix="brush.uv_sculpt.",
-            type=bpy.types.ToolSettings,
+            type=bpy.types.Brush,
             attr="uv_sculpt_tool",
+            tooldef_keywords=dict(
+                operator="sculpt.uv_sculpt_stroke",
+                keymap="Image Editor Tool: Uv, Sculpt Stroke",
+                draw_cursor=draw_cursor,
+            ),
         )
 
 
index 519217b..461f657 100644 (file)
@@ -2651,6 +2651,7 @@ class VIEW3D_MT_brush_paint_modes(Menu):
         brush = settings.brush
 
         layout.prop(brush, "use_paint_sculpt", text="Sculpt")
+        layout.prop(brush, "use_paint_uv_sculpt", text="UV Sculpt")
         layout.prop(brush, "use_paint_vertex", text="Vertex Paint")
         layout.prop(brush, "use_paint_weight", text="Weight Paint")
         layout.prop(brush, "use_paint_image", text="Texture Paint")
index b0fbf07..56c92b7 100644 (file)
@@ -145,6 +145,7 @@ void BKE_paint_runtime_init(const struct ToolSettings *ts, struct Paint *paint);
 void BKE_paint_cavity_curve_preset(struct Paint *p, int preset);
 
 eObjectMode BKE_paint_object_mode_from_paintmode(ePaintMode mode);
+bool BKE_paint_ensure_from_paintmode(struct Scene *sce, ePaintMode mode);
 struct Paint *BKE_paint_get_active_from_paintmode(struct Scene *sce, ePaintMode mode);
 const struct EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(ePaintMode mode);
 const char *BKE_paint_get_tool_prop_id_from_paintmode(ePaintMode mode);
index c52f827..c55cf18 100644 (file)
@@ -140,6 +140,40 @@ void BKE_paint_reset_overlay_invalid(eOverlayControlFlags flag)
   overlay_flags &= ~(flag);
 }
 
+bool BKE_paint_ensure_from_paintmode(Scene *sce, ePaintMode mode)
+{
+  ToolSettings *ts = sce->toolsettings;
+  Paint **paint_ptr = NULL;
+
+  switch (mode) {
+    case PAINT_MODE_SCULPT:
+      paint_ptr = (Paint **)&ts->sculpt;
+      break;
+    case PAINT_MODE_VERTEX:
+      paint_ptr = (Paint **)&ts->vpaint;
+      break;
+    case PAINT_MODE_WEIGHT:
+      paint_ptr = (Paint **)&ts->wpaint;
+      break;
+    case PAINT_MODE_TEXTURE_2D:
+    case PAINT_MODE_TEXTURE_3D:
+      break;
+    case PAINT_MODE_SCULPT_UV:
+      paint_ptr = (Paint **)&ts->uvsculpt;
+      break;
+    case PAINT_MODE_GPENCIL:
+      paint_ptr = (Paint **)&ts->gp_paint;
+      break;
+    case PAINT_MODE_INVALID:
+      break;
+  }
+  if (paint_ptr && (*paint_ptr == NULL)) {
+    BKE_paint_ensure(ts, paint_ptr);
+    return true;
+  }
+  return false;
+}
+
 Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode)
 {
   if (sce) {
@@ -182,6 +216,7 @@ const EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(ePaintMode mode)
     case PAINT_MODE_TEXTURE_3D:
       return rna_enum_brush_image_tool_items;
     case PAINT_MODE_SCULPT_UV:
+      return rna_enum_brush_uv_sculpt_tool_items;
       return NULL;
     case PAINT_MODE_GPENCIL:
       return rna_enum_brush_gpencil_types_items;
@@ -203,6 +238,8 @@ const char *BKE_paint_get_tool_prop_id_from_paintmode(ePaintMode mode)
     case PAINT_MODE_TEXTURE_2D:
     case PAINT_MODE_TEXTURE_3D:
       return "image_tool";
+    case PAINT_MODE_SCULPT_UV:
+      return "uv_sculpt_tool";
     case PAINT_MODE_GPENCIL:
       return "gpencil_tool";
     default:
@@ -229,10 +266,7 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
         case OB_MODE_PAINT_GPENCIL:
           return &ts->gp_paint->paint;
         case OB_MODE_EDIT:
-          if (ts->use_uv_sculpt) {
-            return &ts->uvsculpt->paint;
-          }
-          return &ts->imapaint.paint;
+          return &ts->uvsculpt->paint;
         default:
           break;
       }
@@ -264,7 +298,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
         if (sima->mode == SI_MODE_PAINT) {
           return &ts->imapaint.paint;
         }
-        else if (ts->use_uv_sculpt) {
+        else if (sima->mode == SI_MODE_UV) {
           return &ts->uvsculpt->paint;
         }
       }
@@ -287,7 +321,6 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
   SpaceImage *sima;
 
   if (sce && view_layer) {
-    ToolSettings *ts = sce->toolsettings;
     Object *obact = NULL;
 
     if (view_layer->basact && view_layer->basact->object) {
@@ -299,7 +332,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
         if (sima->mode == SI_MODE_PAINT) {
           return PAINT_MODE_TEXTURE_2D;
         }
-        else if (ts->use_uv_sculpt) {
+        else if (sima->mode == SI_MODE_UV) {
           return PAINT_MODE_SCULPT_UV;
         }
       }
@@ -318,10 +351,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
         case OB_MODE_TEXTURE_PAINT:
           return PAINT_MODE_TEXTURE_3D;
         case OB_MODE_EDIT:
-          if (ts->use_uv_sculpt) {
-            return PAINT_MODE_SCULPT_UV;
-          }
-          return PAINT_MODE_TEXTURE_2D;
+          return PAINT_MODE_SCULPT_UV;
         default:
           return PAINT_MODE_TEXTURE_2D;
       }
@@ -355,6 +385,8 @@ ePaintMode BKE_paintmode_get_from_tool(const struct bToolRef *tref)
     switch (tref->mode) {
       case SI_MODE_PAINT:
         return PAINT_MODE_TEXTURE_2D;
+      case SI_MODE_UV:
+        return PAINT_MODE_SCULPT_UV;
     }
   }
 
@@ -395,15 +427,14 @@ void BKE_paint_runtime_init(const ToolSettings *ts, Paint *paint)
     paint->runtime.tool_offset = offsetof(Brush, weightpaint_tool);
     paint->runtime.ob_mode = OB_MODE_WEIGHT_PAINT;
   }
+  else if (paint == &ts->uvsculpt->paint) {
+    paint->runtime.tool_offset = offsetof(Brush, uv_sculpt_tool);
+    paint->runtime.ob_mode = OB_MODE_EDIT;
+  }
   else if (paint == &ts->gp_paint->paint) {
     paint->runtime.tool_offset = offsetof(Brush, gpencil_tool);
     paint->runtime.ob_mode = OB_MODE_PAINT_GPENCIL;
   }
-  else if (paint == &ts->uvsculpt->paint) {
-    /* We don't use these yet. */
-    paint->runtime.tool_offset = 0;
-    paint->runtime.ob_mode = 0;
-  }
   else {
     BLI_assert(0);
   }
@@ -421,9 +452,10 @@ uint BKE_paint_get_brush_tool_offset_from_paintmode(const ePaintMode mode)
       return offsetof(Brush, vertexpaint_tool);
     case PAINT_MODE_WEIGHT:
       return offsetof(Brush, weightpaint_tool);
+    case PAINT_MODE_SCULPT_UV:
+      return offsetof(Brush, uv_sculpt_tool);
     case PAINT_MODE_GPENCIL:
       return offsetof(Brush, gpencil_tool);
-    case PAINT_MODE_SCULPT_UV:
     case PAINT_MODE_INVALID:
       break; /* We don't use these yet. */
   }
index 942d5e7..fbf586e 100644 (file)
@@ -70,6 +70,7 @@ void BKE_paint_toolslots_init_from_main(struct Main *bmain)
     paint_toolslots_init(bmain, &ts->sculpt->paint);
     paint_toolslots_init(bmain, &ts->vpaint->paint);
     paint_toolslots_init(bmain, &ts->wpaint->paint);
+    paint_toolslots_init(bmain, &ts->uvsculpt->paint);
     paint_toolslots_init(bmain, &ts->gp_paint->paint);
   }
 }
index c54e60a..45c2a50 100644 (file)
@@ -387,6 +387,13 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
     copy_v2_fl2(scene->safe_areas.action, 0.035f, 0.035f);
   }
 
+  if (app_template == NULL) {
+    /* Enable for UV sculpt (other brush types will be created as needed),
+     * without this the grab brush will be active but not selectable from the list. */
+    Brush *brush = BLI_findstring(&bmain->brushes, "Grab", offsetof(ID, name) + 2);
+    brush->ob_mode |= OB_MODE_EDIT;
+  }
+
   for (Brush *brush = bmain->brushes.first; brush; brush = brush->id.next) {
     brush->blur_kernel_radius = 2;
   }
index ba5a6a8..5bd806b 100644 (file)
@@ -71,9 +71,6 @@ void ED_space_image_scopes_update(const struct bContext *C,
 void ED_space_image_paint_update(struct Main *bmain,
                                  struct wmWindowManager *wm,
                                  struct Scene *scene);
-void ED_space_image_uv_sculpt_update(struct Main *bmain,
-                                     struct wmWindowManager *wm,
-                                     struct Scene *scene);
 
 void ED_image_get_uv_aspect(struct Image *ima, struct ImageUser *iuser, float *aspx, float *aspy);
 void ED_image_mouse_pos(struct SpaceImage *sima,
index 9259afd..8dd2dab 100644 (file)
@@ -178,7 +178,6 @@ void ED_uvedit_add_simple_uvs(struct Main *bmain, struct Scene *scene, struct Ob
 /* uvedit_draw.c */
 void ED_image_draw_cursor(struct ARegion *ar, const float cursor[2]);
 void ED_uvedit_draw_main(struct SpaceImage *sima,
-                         struct ARegion *ar,
                          struct Scene *scene,
                          struct ViewLayer *view_layer,
                          struct Object *obedit,
index 4bd6e8b..795e1dd 100644 (file)
@@ -703,8 +703,6 @@ static int editmode_toggle_exec(bContext *C, wmOperator *op)
     }
   }
 
-  ED_space_image_uv_sculpt_update(bmain, CTX_wm_manager(C), scene);
-
   WM_msg_publish_rna_prop(mbus, &obact->id, obact, Object, mode);
 
   if (G.background == false) {
index 6dcb9f8..c60469e 100644 (file)
@@ -98,7 +98,6 @@ const char *screen_context_dir[] = {
     "weight_paint_object",
     "image_paint_object",
     "particle_edit_object",
-    "uv_sculpt_object",
     "pose_object",
     "sequences",
     "selected_sequences",
@@ -520,22 +519,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 
     return 1;
   }
-  else if (CTX_data_equals(member, "uv_sculpt_object")) {
-    /* TODO(campbell): most likely we change rules for uv_sculpt. */
-    if (obact && (obact->mode & OB_MODE_EDIT)) {
-      const ToolSettings *ts = scene->toolsettings;
-      if (ts->use_uv_sculpt) {
-        if (ED_uvedit_test(obedit)) {
-          WorkSpace *workspace = CTX_wm_workspace(C);
-          if ((workspace->tools_space_type == SPACE_IMAGE) &&
-              (workspace->tools_mode == SI_MODE_UV)) {
-            CTX_data_id_pointer_set(result, &obact->id);
-          }
-        }
-      }
-    }
-    return 1;
-  }
   else if (CTX_data_equals(member, "pose_object")) {
     Object *obpose = BKE_object_pose_armature_get(obact);
     if (obpose) {
index 1a8d2f7..ea48148 100644 (file)
@@ -279,9 +279,6 @@ struct ListBase *ED_image_undosys_step_get_tiles(struct UndoStep *us_p);
 struct ListBase *ED_image_undo_get_tiles(void);
 
 /* sculpt_uv.c */
-bool uv_sculpt_poll(struct bContext *C);
-bool uv_sculpt_keymap_poll(struct bContext *C);
-
 void SCULPT_OT_uv_sculpt_stroke(struct wmOperatorType *ot);
 
 /* paint_utils.c */
index a85a256..f58afcd 100644 (file)
@@ -524,37 +524,6 @@ static void PAINT_OT_brush_select(wmOperatorType *ot)
   RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
 }
 
-static int brush_uv_sculpt_tool_set_exec(bContext *C, wmOperator *op)
-{
-  Brush *brush;
-  Scene *scene = CTX_data_scene(C);
-  ToolSettings *ts = scene->toolsettings;
-  ts->uv_sculpt_tool = RNA_enum_get(op->ptr, "tool");
-  brush = ts->uvsculpt->paint.brush;
-  /* To update toolshelf */
-  WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
-
-  return OPERATOR_FINISHED;
-}
-
-static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot)
-{
-  /* identifiers */
-  ot->name = "UV Sculpt Tool Set";
-  ot->description = "Set the UV sculpt tool";
-  ot->idname = "BRUSH_OT_uv_sculpt_tool_set";
-
-  /* api callbacks */
-  ot->exec = brush_uv_sculpt_tool_set_exec;
-  ot->poll = uv_sculpt_poll;
-
-  /* flags */
-  ot->flag = 0;
-
-  /* props */
-  ot->prop = RNA_def_enum(ot->srna, "tool", rna_enum_uv_sculpt_tool_items, 0, "Tool", "");
-}
-
 /***** Stencil Control *****/
 
 typedef enum {
@@ -1014,7 +983,6 @@ void ED_operatortypes_paint(void)
 
   /* note, particle uses a different system, can be added with existing operators in wm.py */
   WM_operatortype_append(PAINT_OT_brush_select);
-  WM_operatortype_append(BRUSH_OT_uv_sculpt_tool_set);
 
   /* image */
   WM_operatortype_append(PAINT_OT_texture_paint_toggle);
@@ -1101,9 +1069,6 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
   keymap = WM_keymap_ensure(keyconf, "Face Mask", 0, 0);
   keymap->poll = facemask_paint_poll;
 
-  keymap = WM_keymap_ensure(keyconf, "UV Sculpt", 0, 0);
-  keymap->poll = uv_sculpt_keymap_poll;
-
   /* paint stroke */
   keymap = paint_stroke_modal_keymap(keyconf);
   WM_modalkeymap_assign(keymap, "SCULPT_OT_brush_stroke");
index 00336b0..3356edd 100644 (file)
@@ -139,121 +139,6 @@ typedef struct UvSculptData {
   char invert;
 } UvSculptData;
 
-static Brush *uv_sculpt_brush(bContext *C)
-{
-  Scene *scene = CTX_data_scene(C);
-  ToolSettings *settings = scene->toolsettings;
-
-  if (!settings->uvsculpt) {
-    return NULL;
-  }
-  return BKE_paint_brush(&settings->uvsculpt->paint);
-}
-
-static bool uv_sculpt_brush_poll_do(bContext *C, const bool check_region)
-{
-  BMEditMesh *em;
-  int ret;
-  Object *obedit = CTX_data_edit_object(C);
-  SpaceImage *sima = CTX_wm_space_image(C);
-  Scene *scene = CTX_data_scene(C);
-  ToolSettings *toolsettings = scene->toolsettings;
-
-  if (!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH || !sima ||
-      ED_space_image_show_render(sima) || (sima->mode == SI_MODE_PAINT)) {
-    return 0;
-  }
-
-  em = BKE_editmesh_from_object(obedit);
-  ret = EDBM_uv_check(em);
-
-  if (ret) {
-    ARegion *ar = CTX_wm_region(C);
-    if ((!toolsettings->use_uv_sculpt) ||
-        (check_region && ar && (ar->regiontype != RGN_TYPE_WINDOW))) {
-      ret = 0;
-    }
-  }
-
-  return ret;
-}
-
-static bool uv_sculpt_brush_poll(bContext *C)
-{
-  return uv_sculpt_brush_poll_do(C, true);
-}
-
-static void brush_drawcursor_uvsculpt(bContext *C, int x, int y, void *UNUSED(customdata))
-{
-#define PX_SIZE_FADE_MAX 12.0f
-#define PX_SIZE_FADE_MIN 4.0f
-
-  Scene *scene = CTX_data_scene(C);
-  // Brush *brush = image_paint_brush(C);
-  Paint *paint = BKE_paint_get_active_from_context(C);
-  Brush *brush = BKE_paint_brush(paint);
-
-  if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
-    const float size = (float)BKE_brush_size_get(scene, brush);
-    float alpha = 0.5f;
-
-    /* fade out the brush (cheap trick to work around brush interfering with sampling [#])*/
-    if (size < PX_SIZE_FADE_MIN) {
-      return;
-    }
-    else if (size < PX_SIZE_FADE_MAX) {
-      alpha *= (size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
-    }
-
-    uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-    immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-    immUniformColor3fvAlpha(brush->add_col, alpha);
-
-    GPU_line_smooth(true);
-    GPU_blend(true);
-    imm_draw_circle_wire_2d(pos, (float)x, (float)y, size, 40);
-    GPU_blend(false);
-    GPU_line_smooth(false);
-
-    immUnbindProgram();
-  }
-#undef PX_SIZE_FADE_MAX
-#undef PX_SIZE_FADE_MIN
-}
-
-void ED_space_image_uv_sculpt_update(Main *bmain, wmWindowManager *wm, Scene *scene)
-{
-  ToolSettings *settings = scene->toolsettings;
-  if (settings->use_uv_sculpt) {
-    if (settings->uvsculpt == NULL) {
-      settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
-      settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
-      settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
-    }
-    BKE_paint_ensure(settings, (Paint **)&settings->uvsculpt);
-    BKE_paint_init(bmain, scene, PAINT_MODE_SCULPT_UV, PAINT_CURSOR_SCULPT);
-
-    settings->uvsculpt->paint.paint_cursor = WM_paint_cursor_activate(
-        wm, SPACE_IMAGE, RGN_TYPE_WINDOW, uv_sculpt_brush_poll, brush_drawcursor_uvsculpt, NULL);
-  }
-  else {
-    if (settings->uvsculpt) {
-      WM_paint_cursor_end(wm, settings->uvsculpt->paint.paint_cursor);
-      settings->uvsculpt->paint.paint_cursor = NULL;
-    }
-  }
-}
-
-bool uv_sculpt_poll(bContext *C)
-{
-  return uv_sculpt_brush_poll_do(C, true);
-}
-
-bool uv_sculpt_keymap_poll(bContext *C)
-{
-  return uv_sculpt_brush_poll_do(C, false);
-}
-
 /*********** Improved Laplacian Relaxation Operator ************************/
 /* original code by Raul Fernandez Hernandez "farsthary"                   *
  * adapted to uv smoothing by Antony Riakiatakis                           *
@@ -631,8 +516,9 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
     int island_index = 0;
     /* Holds, for each UvElement in elementMap, a pointer to its unique uv.*/
     int *uniqueUv;
-    data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH) ? UV_SCULPT_TOOL_RELAX :
-                                                                          ts->uv_sculpt_tool;
+    data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH) ?
+                     UV_SCULPT_TOOL_RELAX :
+                     ts->uvsculpt->paint.brush->uv_sculpt_tool;
     data->invert = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT) ? 1 : 0;
 
     data->uvsculpt = &ts->uvsculpt->paint;
@@ -951,7 +837,7 @@ void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot)
   /* api callbacks */
   ot->invoke = uv_sculpt_stroke_invoke;
   ot->modal = uv_sculpt_stroke_modal;
-  ot->poll = uv_sculpt_poll;
+  ot->poll = ED_operator_uvedit_space_image;
 
   /* flags */
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
index 248497a..386e258 100644 (file)
@@ -552,9 +552,6 @@ static void image_main_region_init(wmWindowManager *wm, ARegion *ar)
   keymap = WM_keymap_ensure(wm->defaultconf, "UV Editor", 0, 0);
   WM_event_add_keymap_handler(&ar->handlers, keymap);
 
-  keymap = WM_keymap_ensure(wm->defaultconf, "UV Sculpt", 0, 0);
-  WM_event_add_keymap_handler(&ar->handlers, keymap);
-
   /* own keymaps */
   keymap = WM_keymap_ensure(wm->defaultconf, "Image Generic", SPACE_IMAGE, 0);
   WM_event_add_keymap_handler(&ar->handlers, keymap);
@@ -608,7 +605,7 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
 
   ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
 
-  ED_uvedit_draw_main(sima, ar, scene, view_layer, obedit, obact, depsgraph);
+  ED_uvedit_draw_main(sima, scene, view_layer, obedit, obact, depsgraph);
 
   /* check for mask (delay draw) */
   if (ED_space_image_show_uvedit(sima, obedit)) {
index 4fb2c64..804b9c2 100644 (file)
@@ -479,14 +479,12 @@ static void draw_uv_shadows_get(
 }
 
 void ED_uvedit_draw_main(SpaceImage *sima,
-                         ARegion *ar,
                          Scene *scene,
                          ViewLayer *view_layer,
                          Object *obedit,
                          Object *obact,
                          Depsgraph *depsgraph)
 {
-  ToolSettings *toolsettings = scene->toolsettings;
   bool show_uvedit, show_uvshadow, show_texpaint_uvshadow;
 
   show_uvedit = ED_space_image_show_uvedit(sima, obedit);
@@ -509,9 +507,5 @@ void ED_uvedit_draw_main(SpaceImage *sima,
     else {
       draw_uvs_texpaint(scene, obact, depsgraph);
     }
-
-    if (show_uvedit && !(toolsettings->use_uv_sculpt)) {
-      ED_image_draw_cursor(ar, sima->cursor);
-    }
   }
 }
index e699043..7de609a 100644 (file)
@@ -128,15 +128,6 @@ bool ED_uvedit_test(Object *obedit)
   return ret;
 }
 
-static bool ED_operator_uvedit_can_uv_sculpt(struct bContext *C)
-{
-  SpaceImage *sima = CTX_wm_space_image(C);
-  ToolSettings *toolsettings = CTX_data_tool_settings(C);
-  Object *obedit = CTX_data_edit_object(C);
-
-  return ED_space_image_show_uvedit(sima, obedit) && !(toolsettings->use_uv_sculpt);
-}
-
 static int UNUSED_FUNCTION(ED_operator_uvmap_mesh)(bContext *C)
 {
   Object *ob = CTX_data_active_object(C);
@@ -5013,7 +5004,7 @@ void ED_keymap_uvedit(wmKeyConfig *keyconf)
   wmKeyMap *keymap;
 
   keymap = WM_keymap_ensure(keyconf, "UV Editor", 0, 0);
-  keymap->poll = ED_operator_uvedit_can_uv_sculpt;
+  keymap->poll = ED_operator_uvedit;
 }
 
 /** \} */
index c5e9a0d..6f775e4 100644 (file)
@@ -263,6 +263,8 @@ typedef struct Brush {
 
   /** Active sculpt tool. */
   char sculpt_tool;
+  /** Active sculpt tool. */
+  char uv_sculpt_tool;
   /** Active vertex paint. */
   char vertexpaint_tool;
   /** Active weight paint. */
@@ -273,7 +275,7 @@ typedef struct Brush {
   char mask_tool;
   /** Active grease pencil tool. */
   char gpencil_tool;
-  char _pad0[2];
+  char _pad0[1];
 
   float autosmooth_factor;
 
@@ -437,6 +439,13 @@ typedef enum eBrushSculptTool {
   SCULPT_TOOL_MASK = 19,
 } eBrushSculptTool;
 
+/* Brush.uv_sculpt_tool */
+typedef enum eBrushUVSculptTool {
+  UV_SCULPT_TOOL_GRAB = 0,
+  UV_SCULPT_TOOL_RELAX = 1,
+  UV_SCULPT_TOOL_PINCH = 2,
+} eBrushUVSculptTool;
+
 /** When #BRUSH_ACCUMULATE is used */
 #define SCULPT_TOOL_HAS_ACCUMULATE(t) \
   ELEM(t, \
index a4f1391..79143ba 100644 (file)
@@ -803,11 +803,6 @@ typedef struct RenderProfile {
 #define UV_SCULPT_LOCK_BORDERS 1
 #define UV_SCULPT_ALL_ISLANDS 2
 
-/* ToolSettings.uv_sculpt_tool */
-#define UV_SCULPT_TOOL_PINCH 1
-#define UV_SCULPT_TOOL_RELAX 2
-#define UV_SCULPT_TOOL_GRAB 3
-
 /* ToolSettings.uv_relax_method */
 #define UV_SCULPT_TOOL_RELAX_LAPLACIAN 1
 #define UV_SCULPT_TOOL_RELAX_HC 2
@@ -1488,10 +1483,8 @@ typedef struct ToolSettings {
   char vgroupsubset;
 
   /* UV painting */
-  char _pad2[1];
-  char use_uv_sculpt;
+  char _pad2[3];
   char uv_sculpt_settings;
-  char uv_sculpt_tool;
   char uv_relax_method;
   /* XXX: these sculpt_paint_* fields are deprecated, use the
    * unified_paint_settings field instead! */
index 5679154..119186f 100644 (file)
@@ -114,6 +114,7 @@ extern const EnumPropertyItem rna_enum_operator_return_items[];
 extern const EnumPropertyItem rna_enum_operator_property_tags[];
 
 extern const EnumPropertyItem rna_enum_brush_sculpt_tool_items[];
+extern const EnumPropertyItem rna_enum_brush_uv_sculpt_tool_items[];
 extern const EnumPropertyItem rna_enum_brush_vertex_tool_items[];
 extern const EnumPropertyItem rna_enum_brush_weight_tool_items[];
 extern const EnumPropertyItem rna_enum_brush_gpencil_types_items[];
index d5c9dfb..40c3a75 100644 (file)
@@ -94,6 +94,13 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
+const EnumPropertyItem rna_enum_brush_uv_sculpt_tool_items[] = {
+    {UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"},
+    {UV_SCULPT_TOOL_RELAX, "RELAX", 0, "Relax", "Relax UVs"},
+    {UV_SCULPT_TOOL_PINCH, "PINCH", 0, "Pinch", "Pinch UVs"},
+    {0, NULL, 0, NULL, NULL},
+};
+
 const EnumPropertyItem rna_enum_brush_vertex_tool_items[] = {
     {VPAINT_TOOL_DRAW, "DRAW", ICON_BRUSH_MIX, "Draw", ""},
     {VPAINT_TOOL_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", ""},
@@ -1575,6 +1582,11 @@ static void rna_def_brush(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "Sculpt Tool", "");
   RNA_def_property_update(prop, 0, "rna_Brush_update_and_reset_icon");
 
+  prop = RNA_def_property(srna, "uv_sculpt_tool", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_items(prop, rna_enum_brush_uv_sculpt_tool_items);
+  RNA_def_property_ui_text(prop, "Sculpt Tool", "");
+  RNA_def_property_update(prop, 0, "rna_Brush_update_and_reset_icon");
+
   prop = RNA_def_property(srna, "vertex_tool", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_sdna(prop, NULL, "vertexpaint_tool");
   RNA_def_property_enum_items(prop, rna_enum_brush_vertex_tool_items);
@@ -2105,6 +2117,10 @@ static void rna_def_brush(BlenderRNA *brna)
   RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_SCULPT);
   RNA_def_property_ui_text(prop, "Use Sculpt", "Use this brush in sculpt mode");
 
+  prop = RNA_def_property(srna, "use_paint_uv_sculpt", PROP_BOOLEAN, PROP_NONE);
+  RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_EDIT);
+  RNA_def_property_ui_text(prop, "Use UV Sculpt", "Use this brush in UV sculpt mode");
+
   prop = RNA_def_property(srna, "use_paint_vertex", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "ob_mode", OB_MODE_VERTEX_PAINT);
   RNA_def_property_ui_text(prop, "Use Vertex", "Use this brush in vertex paint mode");
index fb820f9..6f6699f 100644 (file)
@@ -106,13 +106,6 @@ static const EnumPropertyItem uv_sculpt_relaxation_items[] = {
 };
 #endif
 
-const EnumPropertyItem rna_enum_uv_sculpt_tool_items[] = {
-    {UV_SCULPT_TOOL_PINCH, "PINCH", 0, "Pinch", "Pinch UVs"},
-    {UV_SCULPT_TOOL_RELAX, "RELAX", 0, "Relax", "Relax UVs"},
-    {UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"},
-    {0, NULL, 0, NULL, NULL},
-};
-
 const EnumPropertyItem rna_enum_snap_target_items[] = {
     {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target"},
     {SCE_SNAP_TARGET_CENTER, "CENTER", 0, "Center", "Snap transformation center onto target"},
@@ -708,13 +701,6 @@ static void rna_GPencilInterpolateSettings_type_set(PointerRNA *ptr, int value)
   }
 }
 
-static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain,
-                                                  Scene *scene,
-                                                  PointerRNA *UNUSED(ptr))
-{
-  ED_space_image_uv_sculpt_update(bmain, bmain->wm.first, scene);
-}
-
 /* Read-only Iterator of all the scene objects. */
 
 static void rna_Scene_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@@ -2751,13 +2737,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
   RNA_def_property_pointer_sdna(prop, NULL, "particle");
   RNA_def_property_ui_text(prop, "Particle Edit", "");
 
-  prop = RNA_def_property(srna, "use_uv_sculpt", PROP_BOOLEAN, PROP_NONE);
-  RNA_def_property_boolean_sdna(prop, NULL, "use_uv_sculpt", 1);
-  RNA_def_property_ui_text(prop, "UV Sculpt", "Enable brush for UV sculpting");
-  RNA_def_property_ui_icon(prop, ICON_TPAINT_HLT, 0);
-  RNA_def_property_update(
-      prop, NC_SPACE | ND_SPACE_IMAGE, "rna_SpaceImageEditor_uv_sculpt_update");
-
   prop = RNA_def_property(srna, "uv_sculpt_lock_borders", PROP_BOOLEAN, PROP_NONE);
   RNA_def_property_boolean_sdna(prop, NULL, "uv_sculpt_settings", UV_SCULPT_LOCK_BORDERS);
   RNA_def_property_ui_text(prop, "Lock Borders", "Disable editing of boundary edges");
@@ -2766,11 +2745,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
   RNA_def_property_boolean_sdna(prop, NULL, "uv_sculpt_settings", UV_SCULPT_ALL_ISLANDS);
   RNA_def_property_ui_text(prop, "Sculpt All Islands", "Brush operates on all islands");
 
-  prop = RNA_def_property(srna, "uv_sculpt_tool", PROP_ENUM, PROP_NONE);
-  RNA_def_property_enum_sdna(prop, NULL, "uv_sculpt_tool");
-  RNA_def_property_enum_items(prop, rna_enum_uv_sculpt_tool_items);
-  RNA_def_property_ui_text(prop, "UV Sculpt Tools", "Select Tools for the UV sculpt brushes");
-
   prop = RNA_def_property(srna, "uv_relax_method", PROP_ENUM, PROP_NONE);
   RNA_def_property_enum_sdna(prop, NULL, "uv_relax_method");
   RNA_def_property_enum_items(prop, uv_sculpt_relaxation_items);
index be76a81..2791c49 100644 (file)
@@ -365,6 +365,12 @@ static bool rna_Brush_mode_with_tool_poll(PointerRNA *ptr, PointerRNA value)
     }
     mode = OB_MODE_SCULPT;
   }
+  else if (paint_contains_brush_slot(&ts->uvsculpt->paint, tslot, &slot_index)) {
+    if (slot_index != brush->uv_sculpt_tool) {
+      return false;
+    }
+    mode = OB_MODE_EDIT;
+  }
   else if (paint_contains_brush_slot(&ts->vpaint->paint, tslot, &slot_index)) {
     if (slot_index != brush->vertexpaint_tool) {
       return false;
index 37a7ed4..626e9e8 100644 (file)
@@ -295,9 +295,6 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
       case CTX_MODE_SCULPT:
         km = WM_keymap_find_all(C, "Sculpt", 0, 0);
         break;
-      case CTX_MODE_EDIT_MESH:
-        km = WM_keymap_find_all(C, "UV Sculpt", 0, 0);
-        break;
       default:
         break;
     }
index 0abb567..dc0f02f 100644 (file)
@@ -169,14 +169,6 @@ void WM_toolsystem_unlink(bContext *C, WorkSpace *workspace, const bToolKey *tke
   }
 }
 
-static void toolsystem_ref_link__refresh_image_uv_sculpt(bContext *C, Scene *scene)
-{
-  PointerRNA ptr;
-  RNA_pointer_create(&scene->id, &RNA_ToolSettings, scene->toolsettings, &ptr);
-  PropertyRNA *prop = RNA_struct_find_property(&ptr, "use_uv_sculpt");
-  RNA_property_update(C, &ptr, prop);
-}
-
 /**
  * \see #toolsystem_ref_link
  */
@@ -244,29 +236,6 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre
         }
       }
     }
-    else if ((tref->space_type == SPACE_IMAGE) && (tref->mode == SI_MODE_UV)) {
-      /* Note that switching uv-sculpt boolean is a hack at the moment.
-       * It would be best to make this either an operator or a higher level mode
-       * (like mesh-object sculpt mode). */
-      const EnumPropertyItem *items = rna_enum_uv_sculpt_tool_items;
-      const int i = RNA_enum_from_identifier(items, tref_rt->data_block);
-      if (i != -1) {
-        const int value = items[i].value;
-        wmWindowManager *wm = bmain->wm.first;
-        for (wmWindow *win = wm->windows.first; win; win = win->next) {
-          if (workspace == WM_window_get_active_workspace(win)) {
-            Scene *scene = WM_window_get_active_scene(win);
-            ToolSettings *ts = scene->toolsettings;
-            ts->uv_sculpt_tool = value;
-
-            if (ts->use_uv_sculpt == false) {
-              ts->use_uv_sculpt = true;
-              toolsystem_ref_link__refresh_image_uv_sculpt(C, scene);
-            }
-          }
-        }
-      }
-    }
     else {
       const ePaintMode paint_mode = BKE_paintmode_get_from_tool(tref);
       BLI_assert(paint_mode != PAINT_MODE_INVALID);
@@ -280,6 +249,7 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre
         for (wmWindow *win = wm->windows.first; win; win = win->next) {
           if (workspace == WM_window_get_active_workspace(win)) {
             Scene *scene = WM_window_get_active_scene(win);
+            BKE_paint_ensure_from_paintmode(scene, paint_mode);
             Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
             struct Brush *brush = BKE_paint_toolslots_brush_get(paint, slot_index);
             if (brush == NULL) {
@@ -300,23 +270,6 @@ static void toolsystem_ref_link(bContext *C, WorkSpace *workspace, bToolRef *tre
       }
     }
   }
-  else {
-    /* XXX, this part is weak, disables uv_sculpt when non uv-tool set. */
-    if ((tref->space_type == SPACE_IMAGE) && (tref->mode == SI_MODE_UV)) {
-      Main *bmain = CTX_data_main(C);
-      wmWindowManager *wm = bmain->wm.first;
-      for (wmWindow *win = wm->windows.first; win; win = win->next) {
-        if (workspace == WM_window_get_active_workspace(win)) {
-          Scene *scene = WM_window_get_active_scene(win);
-          ToolSettings *ts = scene->toolsettings;
-          if (ts->use_uv_sculpt == true) {
-            ts->use_uv_sculpt = false;
-            toolsystem_ref_link__refresh_image_uv_sculpt(C, scene);
-          }
-        }
-      }
-    }
-  }
 }
 
 static void toolsystem_refresh_ref(bContext *C, WorkSpace *workspace, bToolRef *tref)
@@ -489,17 +442,6 @@ void WM_toolsystem_ref_sync_from_context(Main *bmain, WorkSpace *workspace, bToo
         }
       }
     }
-    else if ((tref->space_type == SPACE_IMAGE) && (tref->mode == SI_MODE_UV)) {
-      if (ob->mode & OB_MODE_EDIT) {
-        const EnumPropertyItem *items = rna_enum_uv_sculpt_tool_items;
-        const int i = RNA_enum_from_value(items, ts->uv_sculpt_tool);
-        const EnumPropertyItem *item = &items[i];
-        if (!STREQ(tref_rt->data_block, item->identifier)) {
-          STRNCPY(tref_rt->data_block, item->identifier);
-          SNPRINTF(tref->idname, "builtin_brush.%s", item->name);
-        }
-      }
-    }
     else {
       const ePaintMode paint_mode = BKE_paintmode_get_from_tool(tref);
       Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);