diff --git a/scripts/startup/bl_ui/properties_paint_common.py b/scripts/startup/bl_ui/properties_paint_common.py index 80d8d3a6b1a..a19a80f4cd8 100644 --- a/scripts/startup/bl_ui/properties_paint_common.py +++ b/scripts/startup/bl_ui/properties_paint_common.py @@ -1171,7 +1171,7 @@ def brush_shared_settings(layout, context, brush, popover=False): layout.row().prop(brush, "direction", expand=True) -def brush_settings_advanced(layout, context, brush, popover=False): +def brush_settings_advanced(layout, context, settings, brush, popover=False): """Draw advanced brush settings for Sculpt, Texture/Vertex/Weight Paint modes.""" mode = UnifiedPaintPanel.get_brush_mode(context) @@ -1317,8 +1317,8 @@ def brush_settings_advanced(layout, context, brush, popover=False): elif brush.image_tool == 'CLONE': if mode == 'PAINT_2D': - layout.prop(brush, "clone_image", text="Image") - layout.prop(brush, "clone_alpha", text="Alpha") + layout.prop(settings, "clone_image", text="Image") + layout.prop(settings, "clone_alpha", text="Alpha") # Vertex Paint # elif mode == 'PAINT_VERTEX': diff --git a/scripts/startup/bl_ui/space_image.py b/scripts/startup/bl_ui/space_image.py index a39c003473a..56fe8815e06 100644 --- a/scripts/startup/bl_ui/space_image.py +++ b/scripts/startup/bl_ui/space_image.py @@ -1255,7 +1255,7 @@ class IMAGE_PT_paint_settings_advanced(Panel, ImagePaintPanel): settings = context.tool_settings.image_paint brush = settings.brush if brush: - brush_settings_advanced(layout.column(), context, brush, self.is_popover) + brush_settings_advanced(layout.column(), context, settings, brush, self.is_popover) class IMAGE_PT_paint_color(Panel, ImagePaintPanel): diff --git a/scripts/startup/bl_ui/space_view3d_toolbar.py b/scripts/startup/bl_ui/space_view3d_toolbar.py index dc548b85f4c..ebbd6de1158 100644 --- a/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -408,7 +408,7 @@ class VIEW3D_PT_tools_brush_settings_advanced(Panel, View3DPaintBrushPanel): settings = UnifiedPaintPanel.paint_settings(context) brush = settings.brush - brush_settings_advanced(layout.column(), context, brush, self.is_popover) + brush_settings_advanced(layout.column(), context, settings, brush, self.is_popover) class VIEW3D_PT_tools_brush_color(Panel, View3DPaintPanel): diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index abaff3b9430..d5668563e8a 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,7 +31,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 28 +#define BLENDER_FILE_SUBVERSION 29 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 92e73634ce7..e10a5f6b92a 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -162,18 +162,6 @@ static void brush_make_local(Main *bmain, ID *id, const int flags) bool force_local, force_copy; BKE_lib_id_make_local_generic_action_define(bmain, id, flags, &force_local, &force_copy); - if (brush->clone.image) { - /* Special case: `ima` always local immediately. - * Clone image should only have one user anyway. */ - /* FIXME: Recursive calls affecting other non-embedded IDs are really bad and should be avoided - * in IDType callbacks. Higher-level ID management code usually does not expect such things and - * does not deal properly with it. */ - /* NOTE: assert below ensures that the comment above is valid, and that exception is - * acceptable for the time being. */ - BKE_lib_id_make_local(bmain, &brush->clone.image->id, LIB_ID_MAKELOCAL_ASSET_DATA_CLEAR); - BLI_assert(!ID_IS_LINKED(brush->clone.image) && brush->clone.image->id.newid == nullptr); - } - if (force_local) { BKE_lib_id_clear_library_data(bmain, &brush->id, flags); BKE_lib_id_expand_local(bmain, &brush->id, flags); @@ -200,7 +188,6 @@ static void brush_foreach_id(ID *id, LibraryForeachIDData *data) Brush *brush = (Brush *)id; BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->toggle_brush, IDWALK_CB_NOP); - BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->clone.image, IDWALK_CB_NOP); BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->paint_curve, IDWALK_CB_USER); if (brush->gpencil_settings) { BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, brush->gpencil_settings->material, IDWALK_CB_USER); @@ -505,7 +492,6 @@ static void brush_defaults(Brush *brush) FROM_DEFAULT(disconnected_distance_max); FROM_DEFAULT(sculpt_plane); FROM_DEFAULT(plane_offset); - FROM_DEFAULT(clone.alpha); FROM_DEFAULT(normal_weight); FROM_DEFAULT(fill_threshold); FROM_DEFAULT(flag); diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 7cda595ed6e..085bbbd4ebe 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -1142,14 +1142,6 @@ void do_versions_after_linking_300(FileData * /*fd*/, Main *bmain) imapaint->clone = nullptr; } } - - LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { - if (brush->clone.image != nullptr && - ELEM(brush->clone.image->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) - { - brush->clone.image = nullptr; - } - } } if (!MAIN_VERSION_FILE_ATLEAST(bmain, 300, 28)) { diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 9c122ba5b26..fc4290f15e2 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -5828,6 +5828,13 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 404, 29)) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + ToolSettings *ts = scene->toolsettings; + ts->imapaint.clone_alpha = 0.5f; + } + } + /* Always run this versioning; meshes are written with the legacy format which always needs to * be converted to the new format on file load. Can be moved to a subversion check in a larger * breaking release. */ diff --git a/source/blender/draw/engines/overlay/overlay_next_mesh.hh b/source/blender/draw/engines/overlay/overlay_next_mesh.hh index 56b63483d52..6d3c23b93e2 100644 --- a/source/blender/draw/engines/overlay/overlay_next_mesh.hh +++ b/source/blender/draw/engines/overlay/overlay_next_mesh.hh @@ -615,10 +615,11 @@ class MeshUVs : Overlay { } { /* Brush Stencil Overlay. */ - const Brush *brush = BKE_paint_brush_for_read(&tool_setting->imapaint.paint); + const ImagePaintSettings &image_paint_settings = tool_setting->imapaint; + const Brush *brush = BKE_paint_brush_for_read(&image_paint_settings.paint); show_stencil_ = space_mode_is_paint && brush && (brush->image_brush_type == IMAGE_PAINT_BRUSH_TYPE_CLONE) && - brush->clone.image; + image_paint_settings.clone; } { /* UDIM Overlay. */ @@ -860,8 +861,8 @@ class MeshUVs : Overlay { pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL); - const Brush *brush = BKE_paint_brush_for_read(&tool_setting->imapaint.paint); - ::Image *stencil_image = brush->clone.image; + const ImagePaintSettings &image_paint_settings = tool_setting->imapaint; + ::Image *stencil_image = image_paint_settings.clone; TextureRef stencil_texture; stencil_texture.wrap(BKE_image_get_gpu_texture(stencil_image, nullptr)); @@ -873,8 +874,8 @@ class MeshUVs : Overlay { pass.bind_texture("imgTexture", stencil_texture); pass.push_constant("imgPremultiplied", true); pass.push_constant("imgAlphaBlend", true); - pass.push_constant("ucolor", float4(1.0f, 1.0f, 1.0f, brush->clone.alpha)); - pass.push_constant("brush_offset", float2(brush->clone.offset)); + pass.push_constant("ucolor", float4(1.0f, 1.0f, 1.0f, image_paint_settings.clone_alpha)); + pass.push_constant("brush_offset", float2(image_paint_settings.clone_offset)); pass.push_constant("brush_scale", float2(stencil_texture.size().xy()) / size_image); pass.draw(res.shapes.quad_solid.get()); } diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index ea99d61f221..bb458305b58 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -326,11 +326,14 @@ static bool image_paint_poll_ignore_tool(bContext *C) static bool image_paint_2d_clone_poll(bContext *C) { + const Scene *scene = CTX_data_scene(C); + const ToolSettings *settings = scene->toolsettings; + const ImagePaintSettings &image_paint_settings = settings->imapaint; Brush *brush = image_paint_brush(C); if (!CTX_wm_region_view3d(C) && ED_image_tools_paint_poll(C)) { if (brush && (brush->image_brush_type == IMAGE_PAINT_BRUSH_TYPE_CLONE)) { - if (brush->clone.image) { + if (image_paint_settings.clone) { return true; } } @@ -514,12 +517,13 @@ struct GrabClone { static void grab_clone_apply(bContext *C, wmOperator *op) { - Brush *brush = image_paint_brush(C); + const Scene *scene = CTX_data_scene(C); + ToolSettings *settings = scene->toolsettings; + ImagePaintSettings &image_paint_settings = settings->imapaint; float delta[2]; RNA_float_get_array(op->ptr, "delta", delta); - add_v2_v2(brush->clone.offset, delta); - BKE_brush_tag_unsaved_changes(brush); + add_v2_v2(image_paint_settings.clone_offset, delta); ED_region_tag_redraw(CTX_wm_region(C)); } @@ -532,11 +536,13 @@ static int grab_clone_exec(bContext *C, wmOperator *op) static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - Brush *brush = image_paint_brush(C); + const Scene *scene = CTX_data_scene(C); + const ToolSettings *settings = scene->toolsettings; + const ImagePaintSettings &image_paint_settings = settings->imapaint; GrabClone *cmv; cmv = MEM_cnew("GrabClone"); - copy_v2_v2(cmv->startoffset, brush->clone.offset); + copy_v2_v2(cmv->startoffset, image_paint_settings.clone_offset); cmv->startx = event->xy[0]; cmv->starty = event->xy[1]; op->customdata = cmv; @@ -548,7 +554,9 @@ static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event) static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event) { - Brush *brush = image_paint_brush(C); + const Scene *scene = CTX_data_scene(C); + ToolSettings *settings = scene->toolsettings; + ImagePaintSettings &image_paint_settings = settings->imapaint; ARegion *region = CTX_wm_region(C); GrabClone *cmv = static_cast(op->customdata); float startfx, startfy, fx, fy, delta[2]; @@ -570,8 +578,7 @@ static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event) delta[1] = fy - startfy; RNA_float_set_array(op->ptr, "delta", delta); - copy_v2_v2(brush->clone.offset, cmv->startoffset); - BKE_brush_tag_unsaved_changes(brush); + copy_v2_v2(image_paint_settings.clone_offset, cmv->startoffset); grab_clone_apply(C, op); break; diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.cc b/source/blender/editors/sculpt_paint/paint_image_2d.cc index b69ed410782..970e898ff77 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.cc +++ b/source/blender/editors/sculpt_paint/paint_image_2d.cc @@ -1299,13 +1299,14 @@ static int paint_2d_op(void *state, const float pos[2]) { ImagePaintState *s = ((ImagePaintState *)state); + const ImagePaintSettings &image_paint_settings = s->scene->toolsettings->imapaint; ImBuf *clonebuf = nullptr, *frombuf; ImBuf *canvas = tile->canvas; ImBuf *ibufb = tile->cache.ibuf; ImagePaintRegion region[4]; short paint_tile = s->symmetry & (PAINT_TILE_X | PAINT_TILE_Y); short blend = s->blend; - const float *offset = s->brush->clone.offset; + const float *offset = image_paint_settings.clone_offset; float liftpos[2]; float mask_max = BKE_brush_alpha_get(s->scene, s->brush); int bpos[2], blastpos[2], bliftpos[2]; @@ -1424,7 +1425,8 @@ static int paint_2d_canvas_set(ImagePaintState *s) { /* set clone canvas */ if (s->brush_type == IMAGE_PAINT_BRUSH_TYPE_CLONE) { - Image *ima = s->brush->clone.image; + const ImagePaintSettings &image_paint_settings = s->scene->toolsettings->imapaint; + Image *ima = image_paint_settings.clone; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, nullptr, nullptr); if (!ima || !ibuf || !(ibuf->byte_buffer.data || ibuf->float_buffer.data)) { @@ -1454,7 +1456,8 @@ static void paint_2d_canvas_free(ImagePaintState *s) for (int i = 0; i < s->num_tiles; i++) { BKE_image_release_ibuf(s->image, s->tiles[i].canvas, nullptr); } - BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, nullptr); + const ImagePaintSettings &image_paint_settings = s->scene->toolsettings->imapaint; + BKE_image_release_ibuf(image_paint_settings.clone, s->clonecanvas, nullptr); if (s->blurkernel) { paint_delete_blur_kernel(s->blurkernel); diff --git a/source/blender/makesdna/DNA_brush_defaults.h b/source/blender/makesdna/DNA_brush_defaults.h index 881c497584e..c070f4df0c2 100644 --- a/source/blender/makesdna/DNA_brush_defaults.h +++ b/source/blender/makesdna/DNA_brush_defaults.h @@ -44,7 +44,6 @@ /* How far above or below the plane that is found by averaging the faces. */ \ .plane_offset = 0.0f, \ .plane_trim = 0.5f, \ - .clone.alpha = 0.5f, \ .normal_weight = 0.0f, \ .fill_threshold = 0.2f, \ \ diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 3234a691c3f..2a71f86a5e7 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -19,16 +19,6 @@ struct Image; struct MTex; struct Material; -typedef struct BrushClone { - /** Image for clone tool. */ - struct Image *image; - /** Offset of clone image from canvas. */ - float offset[2]; - /** Transparency for drawing of clone image. */ - float alpha; - char _pad[4]; -} BrushClone; - typedef struct BrushGpencilSettings { /** Amount of smoothing to apply to newly created strokes. */ float draw_smoothfac; @@ -175,7 +165,6 @@ typedef struct Brush { ID id; - struct BrushClone clone; /** Falloff curve. */ struct CurveMapping *curve; struct MTex mtex; diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h index 953f977931c..8033b7bb989 100644 --- a/source/blender/makesdna/DNA_scene_defaults.h +++ b/source/blender/makesdna/DNA_scene_defaults.h @@ -280,6 +280,7 @@ .paint.flags = PAINT_SHOW_BRUSH, \ .normal_angle = 80, \ .seam_bleed = 2, \ + .clone_alpha = 0.5f, \ } #define _DNA_DEFAULTS_ParticleBrushData \ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 7f56ce983ad..152239204b2 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1041,6 +1041,11 @@ typedef struct ImagePaintSettings { /** Display texture interpolation method. */ int interp; char _pad[4]; + /** Offset of clone image from canvas in Image editor. */ + float clone_offset[2]; + /** Transparency for drawing of clone image in Image editor. */ + float clone_alpha; + char _pad2[4]; } ImagePaintSettings; /** \} */ diff --git a/source/blender/makesrna/intern/rna_brush.cc b/source/blender/makesrna/intern/rna_brush.cc index 86bf971e70a..85919420a7b 100644 --- a/source/blender/makesrna/intern/rna_brush.cc +++ b/source/blender/makesrna/intern/rna_brush.cc @@ -802,12 +802,6 @@ static void rna_Brush_icon_update(Main * /*bmain*/, Scene * /*scene*/, PointerRN WM_main_add_notifier(NC_BRUSH | NA_EDITED, br); } -static bool rna_Brush_imagetype_poll(PointerRNA * /*ptr*/, PointerRNA value) -{ - Image *image = (Image *)value.owner_id; - return image->type != IMA_TYPE_R_RESULT && image->type != IMA_TYPE_COMPOSITE; -} - static void rna_TextureSlot_brush_angle_update(bContext *C, PointerRNA *ptr) { Scene *scene = CTX_data_scene(C); @@ -3906,26 +3900,6 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Brush Icon Filepath", "File path to brush icon"); RNA_def_property_update(prop, 0, "rna_Brush_icon_update"); - /* clone brush */ - prop = RNA_def_property(srna, "clone_image", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, nullptr, "clone.image"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "Clone Image", "Image for clone brushes"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_update"); - RNA_def_property_pointer_funcs(prop, nullptr, nullptr, nullptr, "rna_Brush_imagetype_poll"); - - prop = RNA_def_property(srna, "clone_alpha", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_float_sdna(prop, nullptr, "clone.alpha"); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Clone Alpha", "Opacity of clone image display"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_update"); - - prop = RNA_def_property(srna, "clone_offset", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_sdna(prop, nullptr, "clone.offset"); - RNA_def_property_ui_text(prop, "Clone Offset", ""); - RNA_def_property_ui_range(prop, -1.0f, 1.0f, 10.0f, 3); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_update"); - prop = RNA_def_property(srna, "brush_capabilities", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); RNA_def_property_struct_type(prop, "BrushCapabilities"); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.cc b/source/blender/makesrna/intern/rna_sculpt_paint.cc index fbe4397ae04..9694ed03a6d 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.cc +++ b/source/blender/makesrna/intern/rna_sculpt_paint.cc @@ -1210,6 +1210,18 @@ static void rna_def_image_paint(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Missing Texture", "Image Painting does not have a texture to paint on"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_property(srna, "clone_alpha", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, nullptr, "clone_alpha"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Clone Alpha", "Opacity of clone image display"); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + + prop = RNA_def_property(srna, "clone_offset", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, nullptr, "clone_offset"); + RNA_def_property_ui_text(prop, "Clone Offset", ""); + RNA_def_property_ui_range(prop, -1.0f, 1.0f, 10.0f, 3); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); } static void rna_def_particle_edit(BlenderRNA *brna)