diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index fe0be500cc1..30cd1ad6ea9 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -7144,21 +7144,53 @@ def km_image_editor_tool_uv_rip_region(params): ) -def km_image_editor_tool_uv_sculpt_stroke(params): +def km_image_editor_tool_uv_grab(params): return ( - "Image Editor Tool: Uv, Sculpt Stroke", + "Image Editor Tool: Uv, Grab", {"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', "repeat": True}, - {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, - {"properties": [("scalar", 1.0 / 0.9)]}), - *_template_paint_radial_control("uv_sculpt"), + ("sculpt.uv_sculpt_grab", {"type": params.tool_mouse, "value": 'PRESS'}, None), + ("sculpt.uv_sculpt_grab", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True}, + {"properties": [("use_invert", True)]}), + ("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None), + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", "tool_settings.uv_sculpt.size"), ], }), + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", "tool_settings.uv_sculpt.strength"), ], }), + ]}, + ) + + +def km_image_editor_tool_uv_relax(params): + return ( + "Image Editor Tool: Uv, Relax", + {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'}, + {"items": [ + ("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS'}, None), + ("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True}, + {"properties": [("use_invert", True)]}), + ("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None), + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", "tool_settings.uv_sculpt.size"), ], }), + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", "tool_settings.uv_sculpt.strength"), ], }), + ]}, + ) + + +def km_image_editor_tool_uv_pinch(params): + return ( + "Image Editor Tool: Uv, Pinch", + {"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'}, + {"items": [ + ("sculpt.uv_sculpt_pinch", {"type": params.tool_mouse, "value": 'PRESS'}, None), + ("sculpt.uv_sculpt_pinch", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True}, + {"properties": [("use_invert", True)]}), + ("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None), + ("wm.radial_control", {"type": 'F', "value": 'PRESS'}, + {"properties": [("data_path_primary", "tool_settings.uv_sculpt.size"), ], }), + ("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True}, + {"properties": [("data_path_primary", "tool_settings.uv_sculpt.strength"), ], }), ]}, ) @@ -8920,7 +8952,9 @@ def generate_keymaps(params=None): *(km_image_editor_tool_uv_select_circle(params, fallback=fallback) for fallback in (False, True)), *(km_image_editor_tool_uv_select_lasso(params, fallback=fallback) for fallback in (False, True)), km_image_editor_tool_uv_rip_region(params), - km_image_editor_tool_uv_sculpt_stroke(params), + km_image_editor_tool_uv_grab(params), + km_image_editor_tool_uv_relax(params), + km_image_editor_tool_uv_pinch(params), km_image_editor_tool_uv_move(params), km_image_editor_tool_uv_rotate(params), km_image_editor_tool_uv_scale(params), diff --git a/scripts/startup/bl_ui/space_image.py b/scripts/startup/bl_ui/space_image.py index 5de208286a9..e0eec5a1801 100644 --- a/scripts/startup/bl_ui/space_image.py +++ b/scripts/startup/bl_ui/space_image.py @@ -714,10 +714,6 @@ class IMAGE_HT_tool_header(Header): layout.popover("IMAGE_PT_tools_brush_display") layout.popover("IMAGE_PT_tools_brush_texture") layout.popover("IMAGE_PT_tools_mask_texture") - elif tool_mode == 'UV': - if (tool is not None) and tool.has_datablock: - layout.popover("IMAGE_PT_uv_sculpt_curve") - layout.popover("IMAGE_PT_uv_sculpt_options") def draw_mode_settings(self, context): layout = self.layout @@ -1344,50 +1340,21 @@ class IMAGE_PT_tools_imagepaint_symmetry(BrushButtonsPanel, Panel): row.prop(ipaint, "tile_y", text="Y", toggle=True) -class UVSculptPanel(UnifiedPaintPanel): - @classmethod - def poll(cls, context): - return cls.get_brush_mode(context) == 'UV_SCULPT' - - -class IMAGE_PT_uv_sculpt_brush_select(Panel, BrushSelectPanel, ImagePaintPanel, UVSculptPanel): - bl_context = ".uv_sculpt" - bl_category = "Tool" - bl_label = "Brushes" - - -class IMAGE_PT_uv_sculpt_brush_settings(Panel, ImagePaintPanel, UVSculptPanel): - bl_context = ".uv_sculpt" - bl_category = "Tool" - bl_label = "Brush Settings" - - def draw(self, context): - layout = self.layout - - tool_settings = context.tool_settings - uvsculpt = tool_settings.uv_sculpt - - brush = uvsculpt.brush - - brush_settings(layout.column(), context, brush) - - if brush: - if brush.uv_sculpt_tool == 'RELAX': - # Although this settings is stored in the scene, - # it is only used by a single tool, - # so it doesn't make sense from a user perspective to move it to the Options panel. - layout.prop(tool_settings, "uv_relax_method") - - -class IMAGE_PT_uv_sculpt_curve(Panel, FalloffPanel, ImagePaintPanel, UVSculptPanel): +class IMAGE_PT_uv_sculpt_curve(Panel, ImagePaintPanel): bl_context = ".uv_sculpt" # Dot on purpose (access from top-bar). - bl_parent_id = "IMAGE_PT_uv_sculpt_brush_settings" bl_category = "Tool" bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} + def draw(self, context): + layout = self.layout + props = context.scene.tool_settings.uv_sculpt + layout.prop(props, "curve_preset", text="") + if props.curve_preset == 'CUSTOM': + layout.template_curve_mapping(props, "strength_curve") -class IMAGE_PT_uv_sculpt_options(Panel, ImagePaintPanel, UVSculptPanel): + +class IMAGE_PT_uv_sculpt_options(Panel, ImagePaintPanel): bl_context = ".uv_sculpt" # Dot on purpose (access from top-bar). bl_category = "Tool" bl_label = "Options" @@ -1396,12 +1363,10 @@ class IMAGE_PT_uv_sculpt_options(Panel, ImagePaintPanel, UVSculptPanel): layout = self.layout tool_settings = context.tool_settings - uvsculpt = tool_settings.uv_sculpt col = layout.column() col.prop(tool_settings, "uv_sculpt_lock_borders") col.prop(tool_settings, "uv_sculpt_all_islands") - col.prop(uvsculpt, "show_brush", text="Display Cursor") class ImageScopesPanel: @@ -1776,8 +1741,6 @@ classes = ( IMAGE_PT_paint_curve, IMAGE_PT_tools_brush_display, IMAGE_PT_tools_imagepaint_symmetry, - IMAGE_PT_uv_sculpt_brush_select, - IMAGE_PT_uv_sculpt_brush_settings, IMAGE_PT_uv_sculpt_options, IMAGE_PT_uv_sculpt_curve, IMAGE_PT_view_histogram, diff --git a/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/scripts/startup/bl_ui/space_toolsystem_toolbar.py index 110e89d1539..21bfc08e071 100644 --- a/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -2181,36 +2181,82 @@ class _defs_image_uv_edit: class _defs_image_uv_sculpt: - @staticmethod - def generate_from_brushes(context): - def draw_cursor(context, _tool, xy): + @ToolDef.from_fn + def grab(): + def draw_settings(context, layout, tool): + uv_sculpt = context.scene.tool_settings.uv_sculpt + layout.prop(uv_sculpt, "size") + layout.prop(uv_sculpt, "strength") + layout.popover("IMAGE_PT_uv_sculpt_curve") + layout.popover("IMAGE_PT_uv_sculpt_options") + + 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 + uv_sculpt = context.scene.tool_settings.uv_sculpt + radius = uv_sculpt.size draw_circle_2d(xy, (1.0,) * 4, radius) - return generate_from_enum_ex( - context, - idname_prefix="builtin_brush.", - icon_prefix="brush.uv_sculpt.", - 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, - options={'KEYMAP_FALLBACK'}, - ), + return dict( + idname="sculpt.uv_sculpt_grab", + label="Grab", + icon="brush.uv_sculpt.grab", + keymap=(), + draw_cursor=draw_cursor, + draw_settings=draw_settings, + options={'KEYMAP_FALLBACK'}, + ) + + @ToolDef.from_fn + def relax(): + def draw_settings(context, layout, tool): + uv_sculpt = context.scene.tool_settings.uv_sculpt + layout.prop(uv_sculpt, "size") + layout.prop(uv_sculpt, "strength") + layout.popover("IMAGE_PT_uv_sculpt_curve") + layout.popover("IMAGE_PT_uv_sculpt_options") + + props = tool.operator_properties("sculpt.uv_sculpt_relax") + layout.prop(props, "relax_method", text="Method") + + def draw_cursor(context, tool, xy): + from gpu_extras.presets import draw_circle_2d + uv_sculpt = context.scene.tool_settings.uv_sculpt + radius = uv_sculpt.size + draw_circle_2d(xy, (1.0,) * 4, radius) + + return dict( + idname="sculpt.uv_sculpt_relax", + label="Relax", + icon="brush.uv_sculpt.relax", + keymap=(), + draw_cursor=draw_cursor, + draw_settings=draw_settings, + options={'KEYMAP_FALLBACK'}, + ) + + @ToolDef.from_fn + def pinch(): + def draw_settings(context, layout, tool): + uv_sculpt = context.scene.tool_settings.uv_sculpt + layout.prop(uv_sculpt, "size") + layout.prop(uv_sculpt, "strength") + layout.popover("IMAGE_PT_uv_sculpt_curve") + layout.popover("IMAGE_PT_uv_sculpt_options") + + def draw_cursor(context, tool, xy): + from gpu_extras.presets import draw_circle_2d + uv_sculpt = context.scene.tool_settings.uv_sculpt + radius = uv_sculpt.size + draw_circle_2d(xy, (1.0,) * 4, radius) + + return dict( + idname="sculpt.uv_sculpt_pinch", + label="Pinch", + icon="brush.uv_sculpt.pinch", + keymap=(), + draw_cursor=draw_cursor, + draw_settings=draw_settings, + options={'KEYMAP_FALLBACK'}, ) @@ -3014,11 +3060,9 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): None, _defs_image_uv_edit.rip_region, None, - lambda context: ( - _defs_image_uv_sculpt.generate_from_brushes(context) - if _defs_image_generic.poll_uvedit(context) - else () - ), + _defs_image_uv_sculpt.grab, + _defs_image_uv_sculpt.relax, + _defs_image_uv_sculpt.pinch, ], 'MASK': [ None, diff --git a/source/blender/blenkernel/BKE_brush.hh b/source/blender/blenkernel/BKE_brush.hh index ec7d758057d..83630a52b14 100644 --- a/source/blender/blenkernel/BKE_brush.hh +++ b/source/blender/blenkernel/BKE_brush.hh @@ -10,6 +10,7 @@ * General operations for brushes. */ +#include "DNA_brush_enums.h" #include "DNA_color_types.h" #include "DNA_object_enums.h" @@ -93,6 +94,10 @@ float BKE_brush_curve_strength_clamped(const Brush *br, float p, float len); /** * Uses the brush curve control to find a strength value. */ +float BKE_brush_curve_strength(eBrushCurvePreset preset, + const CurveMapping *cumap, + float distance, + float brush_radius); float BKE_brush_curve_strength(const Brush *br, float p, float len); /* Sampling. */ diff --git a/source/blender/blenkernel/BKE_paint.hh b/source/blender/blenkernel/BKE_paint.hh index 7d974d2db31..54ab8b86320 100644 --- a/source/blender/blenkernel/BKE_paint.hh +++ b/source/blender/blenkernel/BKE_paint.hh @@ -96,7 +96,6 @@ enum class PaintMode : int8_t { Texture3D = 3, /** Image space (2D painting). */ Texture2D = 4, - SculptUV = 5, GPencil = 6, /* Grease Pencil Vertex Paint */ VertexGPencil = 7, @@ -111,8 +110,6 @@ enum class PaintMode : int8_t { Invalid = 12, }; -#define PAINT_MODE_HAS_BRUSH(mode) !ELEM(mode, PaintMode::SculptUV) - /* overlay invalidation */ enum ePaintOverlayControlFlags { PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY = 1, diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index aa9b3339750..896af0690d9 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -2531,20 +2531,24 @@ void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask) } } -float BKE_brush_curve_strength(const Brush *br, float p, const float len) +float BKE_brush_curve_strength(const eBrushCurvePreset preset, + const CurveMapping *cumap, + const float distance, + const float brush_radius) { + float p = distance; float strength = 1.0f; - if (p >= len) { + if (p >= brush_radius) { return 0; } - p = p / len; + p = p / brush_radius; p = 1.0f - p; - switch (br->curve_preset) { + switch (preset) { case BRUSH_CURVE_CUSTOM: - strength = BKE_curvemapping_evaluateF(br->curve, 0, 1.0f - p); + strength = BKE_curvemapping_evaluateF(cumap, 0, 1.0f - p); break; case BRUSH_CURVE_SHARP: strength = p * p; @@ -2578,6 +2582,11 @@ float BKE_brush_curve_strength(const Brush *br, float p, const float len) return strength; } +float BKE_brush_curve_strength(const Brush *br, float p, const float len) +{ + return BKE_brush_curve_strength(eBrushCurvePreset(br->curve_preset), br->curve, p, len); +} + float BKE_brush_curve_strength_clamped(const Brush *br, float p, const float len) { float strength = BKE_brush_curve_strength(br, p, len); diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 97e4896f19d..f259019fa8e 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -346,9 +346,6 @@ bool BKE_paint_ensure_from_paintmode(Scene *sce, PaintMode mode) paint_tmp = (Paint *)&ts->imapaint; paint_ptr = &paint_tmp; break; - case PaintMode::SculptUV: - paint_ptr = (Paint **)&ts->uvsculpt; - break; case PaintMode::GPencil: paint_ptr = (Paint **)&ts->gp_paint; break; @@ -392,8 +389,6 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode) case PaintMode::Texture2D: case PaintMode::Texture3D: return &ts->imapaint.paint; - case PaintMode::SculptUV: - return &ts->uvsculpt->paint; case PaintMode::GPencil: return &ts->gp_paint->paint; case PaintMode::VertexGPencil: @@ -428,8 +423,6 @@ const EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(const PaintMode m case PaintMode::Texture2D: case PaintMode::Texture3D: return rna_enum_brush_image_tool_items; - case PaintMode::SculptUV: - return rna_enum_brush_uv_sculpt_tool_items; case PaintMode::GPencil: return rna_enum_brush_gpencil_types_items; case PaintMode::VertexGPencil: @@ -460,8 +453,6 @@ const char *BKE_paint_get_tool_prop_id_from_paintmode(const PaintMode mode) case PaintMode::Texture2D: case PaintMode::Texture3D: return "image_tool"; - case PaintMode::SculptUV: - return "uv_sculpt_tool"; case PaintMode::GPencil: return "gpencil_tool"; case PaintMode::VertexGPencil: @@ -492,7 +483,6 @@ const char *BKE_paint_get_tool_enum_translation_context_from_paintmode(const Pai return BLT_I18NCONTEXT_ID_BRUSH; case PaintMode::Vertex: case PaintMode::Weight: - case PaintMode::SculptUV: case PaintMode::VertexGPencil: case PaintMode::SculptGPencil: case PaintMode::WeightGPencil: @@ -533,8 +523,6 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer) return &ts->gp_weightpaint->paint; case OB_MODE_SCULPT_CURVES: return &ts->curves_sculpt->paint; - case OB_MODE_EDIT: - return ts->uvsculpt ? &ts->uvsculpt->paint : nullptr; default: break; } @@ -563,9 +551,6 @@ Paint *BKE_paint_get_active_from_context(const bContext *C) if (sima->mode == SI_MODE_PAINT) { return &ts->imapaint.paint; } - if (sima->mode == SI_MODE_UV) { - return &ts->uvsculpt->paint; - } } else { return &ts->imapaint.paint; @@ -594,9 +579,6 @@ PaintMode BKE_paintmode_get_active_from_context(const bContext *C) if (sima->mode == SI_MODE_PAINT) { return PaintMode::Texture2D; } - if (sima->mode == SI_MODE_UV) { - return PaintMode::SculptUV; - } } else { return PaintMode::Texture2D; @@ -624,8 +606,6 @@ PaintMode BKE_paintmode_get_active_from_context(const bContext *C) return PaintMode::Weight; case OB_MODE_TEXTURE_PAINT: return PaintMode::Texture3D; - case OB_MODE_EDIT: - return PaintMode::SculptUV; case OB_MODE_SCULPT_CURVES: return PaintMode::SculptCurves; default: @@ -674,8 +654,6 @@ PaintMode BKE_paintmode_get_from_tool(const bToolRef *tref) switch (tref->mode) { case SI_MODE_PAINT: return PaintMode::Texture2D; - case SI_MODE_UV: - return PaintMode::SculptUV; } } @@ -721,10 +699,6 @@ 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 (ts->uvsculpt && paint == &ts->uvsculpt->paint) { - paint->runtime.tool_offset = offsetof(Brush, uv_sculpt_tool); - paint->runtime.ob_mode = OB_MODE_EDIT; - } else if (ts->gp_paint && paint == &ts->gp_paint->paint) { paint->runtime.tool_offset = offsetof(Brush, gpencil_tool); paint->runtime.ob_mode = OB_MODE_PAINT_GPENCIL_LEGACY; @@ -762,8 +736,6 @@ uint BKE_paint_get_brush_tool_offset_from_paintmode(const PaintMode mode) return offsetof(Brush, vertexpaint_tool); case PaintMode::Weight: return offsetof(Brush, weightpaint_tool); - case PaintMode::SculptUV: - return offsetof(Brush, uv_sculpt_tool); case PaintMode::GPencil: return offsetof(Brush, gpencil_tool); case PaintMode::VertexGPencil: @@ -1104,8 +1076,6 @@ eObjectMode BKE_paint_object_mode_from_paintmode(const PaintMode mode) case PaintMode::Texture2D: case PaintMode::Texture3D: return OB_MODE_TEXTURE_PAINT; - case PaintMode::SculptUV: - return OB_MODE_EDIT; case PaintMode::SculptCurves: return OB_MODE_SCULPT_CURVES; case PaintMode::GPencil: @@ -1140,7 +1110,6 @@ bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint) (Paint *)ts->sculpt, (Paint *)ts->vpaint, (Paint *)ts->wpaint, - (Paint *)ts->uvsculpt, (Paint *)ts->curves_sculpt, (Paint *)&ts->imapaint)); #ifndef NDEBUG @@ -1182,10 +1151,6 @@ bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint) GpWeightPaint *data = MEM_cnew(__func__); paint = &data->paint; } - else if ((UvSculpt **)r_paint == &ts->uvsculpt) { - UvSculpt *data = MEM_cnew(__func__); - paint = &data->paint; - } else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) { CurvesSculpt *data = MEM_cnew(__func__); paint = &data->paint; @@ -1211,17 +1176,15 @@ void BKE_paint_init(Main *bmain, Scene *sce, PaintMode mode, const uchar col[3]) BKE_paint_ensure_from_paintmode(sce, mode); /* If there's no brush, create one */ - if (PAINT_MODE_HAS_BRUSH(mode)) { - Brush *brush = BKE_paint_brush(paint); - if (brush == nullptr) { - eObjectMode ob_mode = BKE_paint_object_mode_from_paintmode(mode); - brush = BKE_brush_first_search(bmain, ob_mode); - if (!brush) { - brush = BKE_brush_add(bmain, "Brush", ob_mode); - id_us_min(&brush->id); /* Fake user only. */ - } - BKE_paint_brush_set(paint, brush); + Brush *brush = BKE_paint_brush(paint); + if (brush == nullptr) { + eObjectMode ob_mode = BKE_paint_object_mode_from_paintmode(mode); + brush = BKE_brush_first_search(bmain, ob_mode); + if (!brush) { + brush = BKE_brush_add(bmain, "Brush", ob_mode); + id_us_min(&brush->id); /* Fake user only. */ } + BKE_paint_brush_set(paint, brush); } copy_v3_v3_uchar(paint->paint_cursor_col, col); diff --git a/source/blender/blenkernel/intern/paint_toolslots.cc b/source/blender/blenkernel/intern/paint_toolslots.cc index 4ab9259de8f..cf97d437eb7 100644 --- a/source/blender/blenkernel/intern/paint_toolslots.cc +++ b/source/blender/blenkernel/intern/paint_toolslots.cc @@ -89,9 +89,6 @@ void BKE_paint_toolslots_init_from_main(Main *bmain) if (ts->wpaint) { paint_toolslots_init_with_runtime(bmain, ts, &ts->wpaint->paint); } - if (ts->uvsculpt) { - paint_toolslots_init_with_runtime(bmain, ts, &ts->uvsculpt->paint); - } if (ts->gp_paint) { paint_toolslots_init_with_runtime(bmain, ts, &ts->gp_paint->paint); } diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 63db33dde2f..7624ee071da 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -725,14 +725,6 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data, } toolsett_old->sculpt->gravity_object = gravity_object_old; } - if (toolsett_old->uvsculpt) { - paint = toolsett->uvsculpt ? &toolsett->uvsculpt->paint : nullptr; - paint_old = &toolsett_old->uvsculpt->paint; - BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL( - data, - do_undo_restore, - scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old)); - } if (toolsett_old->gp_paint) { paint = toolsett->gp_paint ? &toolsett->gp_paint->paint : nullptr; paint_old = &toolsett_old->gp_paint->paint; @@ -1055,9 +1047,8 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres BKE_paint_blend_write(writer, &tos->sculpt->paint); } - if (tos->uvsculpt) { - BLO_write_struct(writer, UvSculpt, tos->uvsculpt); - BKE_paint_blend_write(writer, &tos->uvsculpt->paint); + if (tos->uvsculpt.strength_curve) { + BKE_curvemapping_blend_write(writer, tos->uvsculpt.strength_curve); } if (tos->gp_paint) { BLO_write_struct(writer, GpPaint, tos->gp_paint); @@ -1259,7 +1250,6 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->sculpt); direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->vpaint); direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->wpaint); - direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->uvsculpt); direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_paint); direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_vertexpaint); direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_sculptpaint); @@ -1272,6 +1262,11 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id) sce->toolsettings->particle.scene = nullptr; sce->toolsettings->particle.object = nullptr; sce->toolsettings->gp_sculpt.paintcursor = nullptr; + if (sce->toolsettings->uvsculpt.strength_curve) { + BLO_read_struct(reader, CurveMapping, &sce->toolsettings->uvsculpt.strength_curve); + BKE_curvemapping_blend_read(reader, sce->toolsettings->uvsculpt.strength_curve); + BKE_curvemapping_init(sce->toolsettings->uvsculpt.strength_curve); + } if (sce->toolsettings->sculpt) { BLO_read_struct(reader, CurveMapping, &sce->toolsettings->sculpt->automasking_cavity_curve); @@ -1671,9 +1666,9 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag) BKE_curvemapping_init(ts->sculpt->automasking_cavity_curve_op); } } - if (ts->uvsculpt) { - ts->uvsculpt = static_cast(MEM_dupallocN(ts->uvsculpt)); - BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag); + if (ts->uvsculpt.strength_curve) { + ts->uvsculpt.strength_curve = BKE_curvemapping_copy(ts->uvsculpt.strength_curve); + BKE_curvemapping_init(ts->uvsculpt.strength_curve); } if (ts->gp_paint) { ts->gp_paint = static_cast(MEM_dupallocN(ts->gp_paint)); @@ -1737,9 +1732,8 @@ void BKE_toolsettings_free(ToolSettings *toolsettings) BKE_paint_free(&toolsettings->sculpt->paint); MEM_freeN(toolsettings->sculpt); } - if (toolsettings->uvsculpt) { - BKE_paint_free(&toolsettings->uvsculpt->paint); - MEM_freeN(toolsettings->uvsculpt); + if (toolsettings->uvsculpt.strength_curve) { + BKE_curvemapping_free(toolsettings->uvsculpt.strength_curve); } if (toolsettings->gp_paint) { BKE_paint_free(&toolsettings->gp_paint->paint); diff --git a/source/blender/blenloader/intern/versioning_280.cc b/source/blender/blenloader/intern/versioning_280.cc index 5b4cecb32b1..838b94fef0f 100644 --- a/source/blender/blenloader/intern/versioning_280.cc +++ b/source/blender/blenloader/intern/versioning_280.cc @@ -797,9 +797,6 @@ static void do_version_curvemapping_walker(Main *bmain, void (*callback)(CurveMa if (ts->sculpt) { callback(ts->sculpt->paint.cavity_curve); } - if (ts->uvsculpt) { - callback(ts->uvsculpt->paint.cavity_curve); - } if (ts->gp_paint) { callback(ts->gp_paint->paint.cavity_curve); } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 724a80c6eea..a23e2dd0367 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3491,12 +3491,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } if (!MAIN_VERSION_FILE_ATLEAST(bmain, 302, 6)) { - LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - ToolSettings *ts = scene->toolsettings; - if (ts->uv_relax_method == 0) { - ts->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN; - } - } LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { ToolSettings *tool_settings = scene->toolsettings; tool_settings->snap_flag_seq = tool_settings->snap_flag & diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 7a9d7ab869b..2ced4277762 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -2946,9 +2946,6 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) input_sample_values[2] = ts->curves_sculpt != nullptr ? ts->curves_sculpt->paint.num_input_samples_deprecated : 1; - input_sample_values[3] = ts->uvsculpt != nullptr ? - ts->uvsculpt->paint.num_input_samples_deprecated : - 1; input_sample_values[4] = ts->gp_paint != nullptr ? ts->gp_paint->paint.num_input_samples_deprecated : @@ -3227,6 +3224,18 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 23)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + ToolSettings *ts = scene->toolsettings; + if (!ts->uvsculpt.strength_curve) { + ts->uvsculpt.size = 50; + ts->uvsculpt.strength = 1.0f; + ts->uvsculpt.curve_preset = BRUSH_CURVE_SMOOTH; + ts->uvsculpt.strength_curve = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + } + } + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check. diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 380bc83aedf..71b6728c3bd 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -1215,7 +1215,6 @@ static bool paint_use_2d_cursor(PaintMode mode) return false; case PaintMode::Texture3D: case PaintMode::Texture2D: - case PaintMode::SculptUV: case PaintMode::VertexGPencil: case PaintMode::SculptGPencil: case PaintMode::WeightGPencil: diff --git a/source/blender/editors/sculpt_paint/paint_intern.hh b/source/blender/editors/sculpt_paint/paint_intern.hh index 689a6131645..8b51652f540 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.hh +++ b/source/blender/editors/sculpt_paint/paint_intern.hh @@ -320,7 +320,9 @@ void paint_curve_mask_cache_update(CurveMaskCache *curve_mask_cache, /* `sculpt_uv.cc` */ -void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot); +void SCULPT_OT_uv_sculpt_grab(wmOperatorType *ot); +void SCULPT_OT_uv_sculpt_relax(wmOperatorType *ot); +void SCULPT_OT_uv_sculpt_pinch(wmOperatorType *ot); /* paint_utils.cc */ diff --git a/source/blender/editors/sculpt_paint/paint_ops.cc b/source/blender/editors/sculpt_paint/paint_ops.cc index 0315d329b82..78932b1b6be 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_ops.cc @@ -1517,7 +1517,9 @@ void ED_operatortypes_paint() WM_operatortype_append(PAINT_OT_weight_sample_group); /* uv */ - WM_operatortype_append(SCULPT_OT_uv_sculpt_stroke); + WM_operatortype_append(SCULPT_OT_uv_sculpt_grab); + WM_operatortype_append(SCULPT_OT_uv_sculpt_relax); + WM_operatortype_append(SCULPT_OT_uv_sculpt_pinch); /* vertex selection */ WM_operatortype_append(PAINT_OT_vert_select_all); diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.cc b/source/blender/editors/sculpt_paint/sculpt_uv.cc index f448d5f96f7..7bee9115efa 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.cc +++ b/source/blender/editors/sculpt_paint/sculpt_uv.cc @@ -40,12 +40,25 @@ #include "RNA_access.hh" #include "RNA_define.hh" +#include "RNA_enum_types.hh" #include "paint_intern.hh" #include "uvedit_intern.hh" #include "UI_view2d.hh" +typedef enum eBrushUVSculptTool { + UV_SCULPT_TOOL_GRAB = 0, + UV_SCULPT_TOOL_RELAX = 1, + UV_SCULPT_TOOL_PINCH = 2, +} eBrushUVSculptTool; + +enum { + UV_SCULPT_TOOL_RELAX_LAPLACIAN = 0, + UV_SCULPT_TOOL_RELAX_HC = 1, + UV_SCULPT_TOOL_RELAX_COTAN = 2, +}; + /* When set, the UV element is on the boundary of the graph. * i.e. Instead of a 2-dimensional laplace operator, use a 1-dimensional version. * Visually, UV elements on the graph boundary appear as borders of the UV Island. */ @@ -73,7 +86,7 @@ struct UVInitialStrokeElement { /** index to unique UV. */ int uv; - /** Strength of brush on initial position. */ + /** Strength on initial position. */ float strength; /** initial UV position. */ @@ -91,7 +104,7 @@ struct UVInitialStroke { float init_coord[2]; }; -/** Custom data for UV smoothing brush. */ +/** Custom data for UV smoothing. */ struct UvSculptData { /** * Contains the first of each set of coincident UVs. @@ -111,14 +124,14 @@ struct UvSculptData { /** data for initial stroke, used by tools like grab */ UVInitialStroke *initial_stroke; - /** Timer to be used for airbrush-type brush. */ + /** Timer to be used for airbrush-type. */ wmTimer *timer; /** To determine quickly adjacent UVs. */ UvElementMap *elementMap; - /** UV-smooth Paint for fast reference. */ - Paint *uvsculpt; + /** UV-smooth for fast reference. */ + UvSculpt *uvsculpt; /** Tool to use. duplicating here to change if modifier keys are pressed. */ char tool; @@ -144,6 +157,18 @@ static void apply_sculpt_data_constraints(UvSculptData *sculptdata, float uv[2]) uv[1] = clamp_f(uv[1], v, v + 1.0f); } +static float calc_strength(const UvSculptData *sculptdata, float p, const float len) +{ + float strength = BKE_brush_curve_strength(eBrushCurvePreset(sculptdata->uvsculpt->curve_preset), + sculptdata->uvsculpt->strength_curve, + p, + len); + + CLAMP(strength, 0.0f, 1.0f); + + return strength; +} + /*********** Improved Laplacian Relaxation Operator ************************/ /* original code by Raul Fernandez Hernandez "farsthary" * * adapted to uv smoothing by Antony Riakiatakis * @@ -164,7 +189,6 @@ static void HC_relaxation_iteration_uv(UvSculptData *sculptdata, float diff[2]; int i; const float radius = sqrtf(radius_sq); - Brush *brush = BKE_paint_brush(sculptdata->uvsculpt); Temp_UVData *tmp_uvdata = (Temp_UVData *)MEM_callocN( sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data"); @@ -205,7 +229,7 @@ static void HC_relaxation_iteration_uv(UvSculptData *sculptdata, if (dist <= radius_sq) { UvElement *element; float strength; - strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius); + strength = alpha * calc_strength(sculptdata, sqrtf(dist), radius); sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] + strength * @@ -250,7 +274,6 @@ static void laplacian_relaxation_iteration_uv(UvSculptData *sculptdata, float diff[2]; int i; const float radius = sqrtf(radius_sq); - Brush *brush = BKE_paint_brush(sculptdata->uvsculpt); Temp_UVData *tmp_uvdata = (Temp_UVData *)MEM_callocN( sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data"); @@ -288,7 +311,7 @@ static void laplacian_relaxation_iteration_uv(UvSculptData *sculptdata, if (dist <= radius_sq) { UvElement *element; float strength; - strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius); + strength = alpha * calc_strength(sculptdata, sqrtf(dist), radius); sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] + strength * tmp_uvdata[i].p[0]; @@ -412,14 +435,13 @@ static void relaxation_iteration_uv(UvSculptData *sculptdata, add_weighted_edge(delta_buf, storage, head_prev, head_curr, *luv_prev, *luv_curr, weight_next); } - Brush *brush = BKE_paint_brush(sculptdata->uvsculpt); for (int i = 0; i < sculptdata->totalUniqueUvs; i++) { UvAdjacencyElement *adj_el = &sculptdata->uv[i]; if (adj_el->is_locked) { continue; /* Locked UVs can't move. */ } - /* Is UV within brush's influence? */ + /* Is UV within influence? */ float diff[2]; sub_v2_v2v2(diff, adj_el->uv, mouse_coord); diff[1] /= aspect_ratio; @@ -427,8 +449,7 @@ static void relaxation_iteration_uv(UvSculptData *sculptdata, if (dist_sq > radius_sq) { continue; } - const float strength = alpha * BKE_brush_curve_strength_clamped( - brush, sqrtf(dist_sq), sqrtf(radius_sq)); + const float strength = alpha * calc_strength(sculptdata, sqrtf(dist_sq), sqrtf(radius_sq)); const float *delta_sum = delta_buf[adj_el->element - storage]; @@ -460,15 +481,12 @@ static void uv_sculpt_stroke_apply(bContext *C, const wmEvent *event, Object *obedit) { - Scene *scene = CTX_data_scene(C); ARegion *region = CTX_wm_region(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); UvSculptData *sculptdata = (UvSculptData *)op->customdata; - Brush *brush = BKE_paint_brush(sculptdata->uvsculpt); - ToolSettings *toolsettings = CTX_data_tool_settings(C); eBrushUVSculptTool tool = eBrushUVSculptTool(sculptdata->tool); int invert = sculptdata->invert ? -1 : 1; - float alpha = BKE_brush_alpha_get(scene, brush); + float alpha = sculptdata->uvsculpt->strength; float co[2]; UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); @@ -481,7 +499,7 @@ static void uv_sculpt_stroke_apply(bContext *C, float zoomx, zoomy; ED_space_image_get_zoom(sima, region, &zoomx, &zoomy); - const float radius = BKE_brush_size_get(scene, brush) / (width * zoomx); + const float radius = sculptdata->uvsculpt->size / (width * zoomx); float aspectRatio = width / float(height); /* We will compare squares to save some computation */ @@ -505,7 +523,7 @@ static void uv_sculpt_stroke_apply(bContext *C, if (dist <= radius_sq) { UvElement *element; float strength; - strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius); + strength = alpha * calc_strength(sculptdata, sqrtf(dist), radius); normalize_v2(diff); sculptdata->uv[i].uv[0] -= strength * diff[0] * 0.001f; @@ -531,7 +549,7 @@ static void uv_sculpt_stroke_apply(bContext *C, alpha, radius_sq, aspectRatio, - toolsettings->uv_relax_method); + RNA_enum_get(op->ptr, "relax_method")); break; } case UV_SCULPT_TOOL_GRAB: { @@ -637,11 +655,10 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm UvSculptData *data = MEM_cnew(__func__); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - Brush *brush = BKE_paint_brush(&ts->uvsculpt->paint); op->customdata = data; - BKE_curvemapping_init(brush->curve); + BKE_curvemapping_init(ts->uvsculpt.strength_curve); if (!data) { return nullptr; @@ -658,12 +675,18 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm bool do_island_optimization = !(ts->uv_sculpt_settings & UV_SCULPT_ALL_ISLANDS); int island_index = 0; - data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH) ? - UV_SCULPT_TOOL_RELAX : - eBrushUVSculptTool(brush->uv_sculpt_tool); - data->invert = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT) ? 1 : 0; + if (STREQ(op->type->idname, "SCULPT_OT_uv_sculpt_relax")) { + data->tool = UV_SCULPT_TOOL_RELAX; + } + else if (STREQ(op->type->idname, "SCULPT_OT_uv_sculpt_grab")) { + data->tool = UV_SCULPT_TOOL_GRAB; + } + else { + data->tool = UV_SCULPT_TOOL_PINCH; + } + data->invert = RNA_boolean_get(op->ptr, "use_invert"); - data->uvsculpt = &ts->uvsculpt->paint; + data->uvsculpt = &ts->uvsculpt; /* Winding was added to island detection in 5197aa04c6bd * However the sculpt tools can flip faces, potentially creating orphaned islands. @@ -834,12 +857,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm /* Allocate initial selection for grab tool */ if (data->tool == UV_SCULPT_TOOL_GRAB) { - UvSculptData *sculptdata = (UvSculptData *)op->customdata; - Brush *brush = BKE_paint_brush(sculptdata->uvsculpt); - - float alpha = BKE_brush_alpha_get(scene, brush); - - float radius = BKE_brush_size_get(scene, brush); + float alpha = data->uvsculpt->strength; + float radius = data->uvsculpt->size; int width, height; ED_space_image_get_size(sima, &width, &height); float zoomx, zoomy; @@ -875,7 +894,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm float dist = dot_v2v2(diff, diff); if (dist <= radius_sq) { float strength; - strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius); + strength = alpha * calc_strength(data, sqrtf(dist), radius); data->initial_stroke->initialSelection[counter].uv = i; data->initial_stroke->initialSelection[counter].strength = strength; @@ -946,57 +965,78 @@ static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, const wmEvent *ev return OPERATOR_RUNNING_MODAL; } -static bool uv_sculpt_stroke_poll(bContext *C) +static void register_common_props(wmOperatorType *ot) { - if (ED_operator_uvedit_space_image(C)) { - /* While these values could be initialized on demand, - * the only case this would be useful is running from the operator search popup. - * This is such a corner case that it's simpler to check a brush has already been created - * (something the tool system ensures). */ - Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; - Brush *brush = BKE_paint_brush(&ts->uvsculpt->paint); - if (brush != nullptr) { - return true; - } - } - return false; -} - -void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot) -{ - static const EnumPropertyItem stroke_mode_items[] = { - {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Regular", "Apply brush normally"}, - {BRUSH_STROKE_INVERT, - "INVERT", - 0, - "Invert", - "Invert action of brush for duration of stroke"}, - {BRUSH_STROKE_SMOOTH, - "RELAX", - 0, - "Relax", - "Switch brush to relax mode for duration of stroke"}, - {0}, - }; - - /* identifiers */ - ot->name = "Sculpt UVs"; - ot->description = "Sculpt UVs using a brush"; - ot->idname = "SCULPT_OT_uv_sculpt_stroke"; - - /* api callbacks */ - ot->invoke = uv_sculpt_stroke_invoke; - ot->modal = uv_sculpt_stroke_modal; - ot->poll = uv_sculpt_stroke_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ PropertyRNA *prop; - prop = RNA_def_enum( - ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL, "Mode", "Stroke Mode"); + prop = RNA_def_boolean( + ot->srna, "use_invert", false, "Invert", "Invert action for the duration of the stroke"); RNA_def_property_flag(prop, PropertyFlag(PROP_SKIP_SAVE)); } + +void SCULPT_OT_uv_sculpt_grab(wmOperatorType *ot) +{ + ot->name = "Grab UVs"; + ot->description = "Grab UVs"; + ot->idname = "SCULPT_OT_uv_sculpt_grab"; + + ot->invoke = uv_sculpt_stroke_invoke; + ot->modal = uv_sculpt_stroke_modal; + ot->poll = ED_operator_uvedit_space_image; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + register_common_props(ot); +} + +void SCULPT_OT_uv_sculpt_relax(wmOperatorType *ot) +{ + ot->name = "Relax UVs"; + ot->description = "Relax UVs"; + ot->idname = "SCULPT_OT_uv_sculpt_relax"; + + ot->invoke = uv_sculpt_stroke_invoke; + ot->modal = uv_sculpt_stroke_modal; + ot->poll = ED_operator_uvedit_space_image; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + register_common_props(ot); + + static const EnumPropertyItem relax_method_items[] = { + {UV_SCULPT_TOOL_RELAX_LAPLACIAN, + "LAPLACIAN", + 0, + "Laplacian", + "Use Laplacian method for relaxation"}, + {UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"}, + {UV_SCULPT_TOOL_RELAX_COTAN, + "COTAN", + 0, + "Geometry", + "Use Geometry (cotangent) relaxation, making UVs follow the underlying 3D geometry"}, + {0, nullptr, 0, nullptr, nullptr}, + }; + + RNA_def_enum(ot->srna, + "relax_method", + relax_method_items, + CURVE_PRESET_SMOOTH, + "Relax Method", + "Algorithm used for UV relaxation"); +} + +void SCULPT_OT_uv_sculpt_pinch(wmOperatorType *ot) +{ + ot->name = "Pinch UVs"; + ot->description = "Pinch UVs"; + ot->idname = "SCULPT_OT_uv_sculpt_pinch"; + + ot->invoke = uv_sculpt_stroke_invoke; + ot->modal = uv_sculpt_stroke_modal; + ot->poll = ED_operator_uvedit_space_image; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + register_common_props(ot); +} diff --git a/source/blender/editors/space_image/image_ops.cc b/source/blender/editors/space_image/image_ops.cc index f3b289790c7..7e13392986a 100644 --- a/source/blender/editors/space_image/image_ops.cc +++ b/source/blender/editors/space_image/image_ops.cc @@ -330,10 +330,8 @@ bool space_image_main_region_poll(bContext *C) static bool space_image_main_area_not_uv_brush_poll(bContext *C) { SpaceImage *sima = CTX_wm_space_image(C); - Scene *scene = CTX_data_scene(C); - ToolSettings *toolsettings = scene->toolsettings; - if (sima && !toolsettings->uvsculpt && (CTX_data_edit_object(C) == nullptr)) { + if (sima && (CTX_data_edit_object(C) == nullptr)) { return true; } diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index 8ce636f5ff9..e338c0ed568 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -483,13 +483,6 @@ typedef enum eBrushSculptTool { SCULPT_TOOL_DISPLACEMENT_SMEAR = 32, } eBrushSculptTool; -/** #Brush.uv_sculpt_tool */ -typedef enum eBrushUVSculptTool { - UV_SCULPT_TOOL_GRAB = 0, - UV_SCULPT_TOOL_RELAX = 1, - UV_SCULPT_TOOL_PINCH = 2, -} eBrushUVSculptTool; - /* Brush.curves_sculpt_tool. */ typedef enum eBrushCurvesSculptTool { CURVES_SCULPT_TOOL_COMB = 0, diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 431d9c74194..9d7f630ee0c 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -273,8 +273,6 @@ 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. */ @@ -293,7 +291,7 @@ typedef struct Brush { char gpencil_weight_tool; /** Active curves sculpt tool (#eBrushCurvesSculptTool). */ char curves_sculpt_tool; - char _pad1[5]; + char _pad1[6]; float autosmooth_factor; diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h index 60c75b0d765..35eccb3254e 100644 --- a/source/blender/makesdna/DNA_scene_defaults.h +++ b/source/blender/makesdna/DNA_scene_defaults.h @@ -408,8 +408,7 @@ \ /* UV painting */ \ .uv_sculpt_settings = 0, \ - .uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \ -\ + \ /* Placement */ \ .snap_mode_tools = SCE_SNAP_TO_GEOM,\ .plane_axis = 2,\ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index fd50d44a168..f1940b309de 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -860,13 +860,6 @@ enum { UV_SCULPT_ALL_ISLANDS = 2, }; -/** #ToolSettings::uv_relax_method */ -enum { - UV_SCULPT_TOOL_RELAX_LAPLACIAN = 1, - UV_SCULPT_TOOL_RELAX_HC = 2, - UV_SCULPT_TOOL_RELAX_COTAN = 3, -}; - /* Stereo Flags. */ #define STEREO_RIGHT_NAME "right" #define STEREO_LEFT_NAME "left" @@ -1100,7 +1093,11 @@ typedef struct CurvesSculpt { } CurvesSculpt; typedef struct UvSculpt { - Paint paint; + struct CurveMapping *strength_curve; + int size; + float strength; + int8_t curve_preset; /* #eBrushCurvePreset. */ + char _pad[7]; } UvSculpt; /** Grease pencil drawing brushes. */ @@ -1513,7 +1510,7 @@ typedef struct ToolSettings { VPaint *wpaint; Sculpt *sculpt; /** UV smooth. */ - UvSculpt *uvsculpt; + UvSculpt uvsculpt; /** Gpencil paint. */ GpPaint *gp_paint; /** Gpencil vertex paint. */ @@ -1665,10 +1662,11 @@ typedef struct ToolSettings { /* UV painting. */ char uv_sculpt_settings; - char uv_relax_method; char workspace_tool_type; + char _pad5[1]; + /** * XXX: these `sculpt_paint_*` fields are deprecated, use the * unified_paint_settings field instead! diff --git a/source/blender/makesrna/RNA_enum_items.hh b/source/blender/makesrna/RNA_enum_items.hh index 52f6d08ae51..94fb8b4ed56 100644 --- a/source/blender/makesrna/RNA_enum_items.hh +++ b/source/blender/makesrna/RNA_enum_items.hh @@ -109,7 +109,6 @@ DEF_ENUM(rna_enum_operator_property_tag_items) DEF_ENUM(rna_enum_brush_automasking_flag_items) DEF_ENUM(rna_enum_brush_sculpt_tool_items) -DEF_ENUM(rna_enum_brush_uv_sculpt_tool_items) DEF_ENUM(rna_enum_brush_vertex_tool_items) DEF_ENUM(rna_enum_brush_weight_tool_items) DEF_ENUM(rna_enum_brush_gpencil_types_items) @@ -118,6 +117,7 @@ DEF_ENUM(rna_enum_brush_gpencil_sculpt_types_items) DEF_ENUM(rna_enum_brush_gpencil_weight_types_items) DEF_ENUM(rna_enum_brush_curves_sculpt_tool_items) DEF_ENUM(rna_enum_brush_image_tool_items) +DEF_ENUM(rna_enum_brush_curve_preset_items) DEF_ENUM(rna_enum_grease_pencil_selectmode_items) diff --git a/source/blender/makesrna/intern/rna_brush.cc b/source/blender/makesrna/intern/rna_brush.cc index 861683a4a04..3644ebc1687 100644 --- a/source/blender/makesrna/intern/rna_brush.cc +++ b/source/blender/makesrna/intern/rna_brush.cc @@ -94,6 +94,20 @@ static const EnumPropertyItem rna_enum_brush_texture_slot_map_texture_mode_items }; #endif +const EnumPropertyItem rna_enum_brush_curve_preset_items[] = { + {BRUSH_CURVE_CUSTOM, "CUSTOM", ICON_RNDCURVE, "Custom", ""}, + {BRUSH_CURVE_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""}, + {BRUSH_CURVE_SMOOTHER, "SMOOTHER", ICON_SMOOTHCURVE, "Smoother", ""}, + {BRUSH_CURVE_SPHERE, "SPHERE", ICON_SPHERECURVE, "Sphere", ""}, + {BRUSH_CURVE_ROOT, "ROOT", ICON_ROOTCURVE, "Root", ""}, + {BRUSH_CURVE_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""}, + {BRUSH_CURVE_LIN, "LIN", ICON_LINCURVE, "Linear", ""}, + {BRUSH_CURVE_POW4, "POW4", ICON_SHARPCURVE, "Sharper", ""}, + {BRUSH_CURVE_INVSQUARE, "INVSQUARE", ICON_INVERSESQUARECURVE, "Inverse Square", ""}, + {BRUSH_CURVE_CONSTANT, "CONSTANT", ICON_NOCURVE, "Constant", ""}, + {0, nullptr, 0, nullptr, nullptr}, +}; + /* Note: we don't actually turn these into a single enum bit-mask property, * instead we construct individual boolean properties. */ const EnumPropertyItem rna_enum_brush_automasking_flag_items[] = { @@ -185,13 +199,6 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = { {0, nullptr, 0, nullptr, nullptr}, }; -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, nullptr, 0, nullptr, nullptr}, -}; - const EnumPropertyItem rna_enum_brush_vertex_tool_items[] = { {VPAINT_TOOL_DRAW, "DRAW", ICON_BRUSH_MIX, "Draw", ""}, {VPAINT_TOOL_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", ""}, @@ -2419,20 +2426,6 @@ static void rna_def_brush(BlenderRNA *brna) {0, nullptr, 0, nullptr, nullptr}, }; - static const EnumPropertyItem brush_curve_preset_items[] = { - {BRUSH_CURVE_CUSTOM, "CUSTOM", ICON_RNDCURVE, "Custom", ""}, - {BRUSH_CURVE_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""}, - {BRUSH_CURVE_SMOOTHER, "SMOOTHER", ICON_SMOOTHCURVE, "Smoother", ""}, - {BRUSH_CURVE_SPHERE, "SPHERE", ICON_SPHERECURVE, "Sphere", ""}, - {BRUSH_CURVE_ROOT, "ROOT", ICON_ROOTCURVE, "Root", ""}, - {BRUSH_CURVE_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""}, - {BRUSH_CURVE_LIN, "LIN", ICON_LINCURVE, "Linear", ""}, - {BRUSH_CURVE_POW4, "POW4", ICON_SHARPCURVE, "Sharper", ""}, - {BRUSH_CURVE_INVSQUARE, "INVSQUARE", ICON_INVERSESQUARECURVE, "Inverse Square", ""}, - {BRUSH_CURVE_CONSTANT, "CONSTANT", ICON_NOCURVE, "Constant", ""}, - {0, nullptr, 0, nullptr, nullptr}, - }; - static const EnumPropertyItem brush_deformation_target_items[] = { {BRUSH_DEFORM_TARGET_GEOMETRY, "GEOMETRY", @@ -2619,11 +2612,6 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_BRUSH); 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, "UV 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, nullptr, "vertexpaint_tool"); RNA_def_property_enum_items(prop, rna_enum_brush_vertex_tool_items); @@ -2703,7 +2691,7 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "curve_preset", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, brush_curve_preset_items); + RNA_def_property_enum_items(prop, rna_enum_brush_curve_preset_items); RNA_def_property_ui_text(prop, "Curve Preset", ""); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVES); /* Abusing id_curves :/ */ RNA_def_property_update(prop, 0, "rna_Brush_update"); diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index 3280fee3027..02df23d16d9 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -85,23 +85,6 @@ const EnumPropertyItem rna_enum_exr_codec_items[] = { }; #endif -#ifndef RNA_RUNTIME -static const EnumPropertyItem uv_sculpt_relaxation_items[] = { - {UV_SCULPT_TOOL_RELAX_LAPLACIAN, - "LAPLACIAN", - 0, - "Laplacian", - "Use Laplacian method for relaxation"}, - {UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"}, - {UV_SCULPT_TOOL_RELAX_COTAN, - "COTAN", - 0, - "Geometry", - "Use Geometry (cotangent) relaxation, making UVs follow the underlying 3D geometry"}, - {0, nullptr, 0, nullptr, nullptr}, -}; -#endif - const EnumPropertyItem rna_enum_snap_source_items[] = { {SCE_SNAP_SOURCE_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target"}, {SCE_SNAP_SOURCE_CENTER, "CENTER", 0, "Center", "Snap transformation center onto target"}, @@ -3328,12 +3311,6 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY); RNA_def_property_ui_text(prop, "Sculpt All Islands", "Brush operates on all islands"); - prop = RNA_def_property(srna, "uv_relax_method", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, nullptr, "uv_relax_method"); - RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY); - RNA_def_property_enum_items(prop, uv_sculpt_relaxation_items); - RNA_def_property_ui_text(prop, "Relaxation Method", "Algorithm used for UV relaxation"); - prop = RNA_def_property(srna, "lock_object_mode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "object_flag", SCE_OBJECT_MODE_LOCK); RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.cc b/source/blender/makesrna/intern/rna_sculpt_paint.cc index 8ca9258118f..f9bba65e0c0 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.cc +++ b/source/blender/makesrna/intern/rna_sculpt_paint.cc @@ -110,6 +110,7 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = { # include "MEM_guardedalloc.h" # include "BKE_collection.hh" +# include "BKE_colortools.hh" # include "BKE_context.hh" # include "BKE_gpencil_legacy.h" # include "BKE_object.hh" @@ -323,12 +324,6 @@ 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; @@ -518,6 +513,18 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA * /*ptr*/) } } +static void rna_UvSculpt_curve_preset_set(PointerRNA *ptr, int value) +{ + Scene *scene = reinterpret_cast(ptr->owner_id); + if (value == BRUSH_CURVE_CUSTOM) { + if (!scene->toolsettings->uvsculpt.strength_curve) { + scene->toolsettings->uvsculpt.strength_curve = BKE_curvemapping_add( + 1, 0.0f, 0.0f, 1.0f, 1.0f); + } + } + scene->toolsettings->uvsculpt.curve_preset = int8_t(value); +} + /** \name Paint mode settings * \{ */ @@ -996,10 +1003,34 @@ static void rna_def_sculpt(BlenderRNA *brna) static void rna_def_uv_sculpt(BlenderRNA *brna) { StructRNA *srna; + PropertyRNA *prop; srna = RNA_def_struct(brna, "UvSculpt", "Paint"); RNA_def_struct_path_func(srna, "rna_UvSculpt_path"); RNA_def_struct_ui_text(srna, "UV Sculpting", ""); + + prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL); + RNA_def_property_ui_range(prop, 1, 500, 1, 1); + RNA_def_property_range(prop, 1, 5000); + RNA_def_property_ui_text(prop, "Size", ""); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + + prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Strength", ""); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + + prop = RNA_def_property(srna, "strength_curve", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "CurveMapping"); + RNA_def_property_pointer_funcs(prop, nullptr, nullptr, nullptr, nullptr); + RNA_def_property_ui_text(prop, "Strength Curve", ""); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + + prop = RNA_def_property(srna, "curve_preset", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, rna_enum_brush_curve_preset_items); + RNA_def_property_ui_text(prop, "Strength Curve Preset", ""); + RNA_def_property_enum_funcs(prop, nullptr, "rna_UvSculpt_curve_preset_set", nullptr); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); } static void rna_def_gp_paint(BlenderRNA *brna)