diff --git a/scripts/startup/bl_ui/properties_paint_common.py b/scripts/startup/bl_ui/properties_paint_common.py index 0647ea7cd90..bc08fdfe284 100644 --- a/scripts/startup/bl_ui/properties_paint_common.py +++ b/scripts/startup/bl_ui/properties_paint_common.py @@ -136,9 +136,13 @@ class BrushAssetShelf: if not shelf_name: return + display_name = brush.name if (brush and show_name) else None + if display_name and brush.has_unsaved_changes: + display_name = display_name + "*" + layout.template_asset_shelf_popover( shelf_name, - name=brush.name if (brush and show_name) else None, + name=display_name, icon='BRUSH_DATA' if not preview_icon_id else 'NONE', icon_value=preview_icon_id, ) @@ -302,6 +306,22 @@ class BrushPanel(UnifiedPaintPanel): class BrushSelectPanel(BrushPanel): bl_label = "Brush Asset" + # Use header preset function to right align the layout. + def draw_header_preset(self, context): + layout = self.layout + + settings = self.paint_settings(context) + if settings is None: + return + + brush = settings.brush + if brush is None: + return + + if brush.has_unsaved_changes and bpy.ops.brush.asset_update.poll(): + layout.label(text="*Unsaved Changes") + layout.separator() + def draw(self, context): layout = self.layout settings = self.paint_settings(context) diff --git a/source/blender/blenkernel/BKE_brush.hh b/source/blender/blenkernel/BKE_brush.hh index 501fd1002be..f867c754841 100644 --- a/source/blender/blenkernel/BKE_brush.hh +++ b/source/blender/blenkernel/BKE_brush.hh @@ -50,6 +50,19 @@ void BKE_brush_init_gpencil_settings(Brush *brush); void BKE_brush_init_curves_sculpt_settings(Brush *brush); +/** + * Tag a linked brush as having changed settings so an indicator can be displayed to the user, + * showing that the brush settings differ from the state of the imported brush asset. Call + * everytime a user visible change to the brush is done. + * + * Since this is meant to indicate brushes that are known to differ from the linked source file, + * tagging is only performed for linked brushes. File local brushes are normal data-blocks that get + * saved with the file, and don't need special attention by the user. + * + * For convenience, null may be passed for \a brush. + */ +void BKE_brush_tag_unsaved_changes(Brush *brush); + Brush *BKE_brush_first_search(Main *bmain, eObjectMode ob_mode); void BKE_brush_jitter_pos(const Scene &scene, diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 7b650472108..e5d88344455 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -10,6 +10,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_ID.h" #include "DNA_brush_types.h" #include "DNA_defaults.h" #include "DNA_material_types.h" @@ -364,6 +365,7 @@ static void brush_blend_read_data(BlendDataReader *reader, ID *id) BKE_previewimg_blend_read(reader, brush->preview); brush->icon_imbuf = nullptr; + brush->has_unsaved_changes = false; } static void brush_blend_read_after_liblink(BlendLibReader * /*reader*/, ID *id) @@ -616,6 +618,13 @@ void BKE_brush_init_curves_sculpt_settings(Brush *brush) settings->curve_parameter_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); } +void BKE_brush_tag_unsaved_changes(Brush *brush) +{ + if (brush && ID_IS_LINKED(brush)) { + brush->has_unsaved_changes = true; + } +} + Brush *BKE_brush_first_search(Main *bmain, const eObjectMode ob_mode) { LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { @@ -747,6 +756,7 @@ void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset) cuma = b->curve->cm; BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_NEGATIVE); BKE_curvemapping_changed(cumap, false); + BKE_brush_tag_unsaved_changes(b); } const MTex *BKE_brush_mask_texture_get(const Brush *brush, const eObjectMode object_mode) @@ -1037,6 +1047,7 @@ void BKE_brush_color_set(Scene *scene, Brush *brush, const float color[3]) } else { copy_v3_v3(brush->rgb, color); + BKE_brush_tag_unsaved_changes(brush); } } @@ -1052,6 +1063,7 @@ void BKE_brush_size_set(Scene *scene, Brush *brush, int size) } else { brush->size = size; + BKE_brush_tag_unsaved_changes(brush); } } @@ -1109,6 +1121,7 @@ void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojec } else { brush->unprojected_radius = unprojected_radius; + BKE_brush_tag_unsaved_changes(brush); } } @@ -1128,6 +1141,7 @@ void BKE_brush_alpha_set(Scene *scene, Brush *brush, float alpha) } else { brush->alpha = alpha; + BKE_brush_tag_unsaved_changes(brush); } } @@ -1154,6 +1168,7 @@ void BKE_brush_weight_set(const Scene *scene, Brush *brush, float value) } else { brush->weight = value; + BKE_brush_tag_unsaved_changes(brush); } } @@ -1173,6 +1188,7 @@ void BKE_brush_input_samples_set(const Scene *scene, Brush *brush, int value) } else { brush->input_samples = value; + BKE_brush_tag_unsaved_changes(brush); } } diff --git a/source/blender/blenkernel/intern/gpencil_legacy.cc b/source/blender/blenkernel/intern/gpencil_legacy.cc index 1992bc15b38..5a34f507391 100644 --- a/source/blender/blenkernel/intern/gpencil_legacy.cc +++ b/source/blender/blenkernel/intern/gpencil_legacy.cc @@ -36,6 +36,7 @@ #include "BKE_action.hh" #include "BKE_anim_data.hh" +#include "BKE_brush.hh" #include "BKE_collection.hh" #include "BKE_colortools.hh" #include "BKE_deform.hh" @@ -1370,6 +1371,7 @@ void BKE_gpencil_brush_material_set(Brush *brush, Material *ma) id_us_plus(&ma->id); } brush->gpencil_settings->material = ma; + BKE_brush_tag_unsaved_changes(brush); } } diff --git a/source/blender/blenkernel/intern/texture.cc b/source/blender/blenkernel/intern/texture.cc index b439032a31b..75c17b1e4df 100644 --- a/source/blender/blenkernel/intern/texture.cc +++ b/source/blender/blenkernel/intern/texture.cc @@ -36,6 +36,7 @@ #include "DNA_object_types.h" #include "DNA_particle_types.h" +#include "BKE_brush.hh" #include "BKE_colorband.hh" #include "BKE_colortools.hh" #include "BKE_icons.h" @@ -551,6 +552,7 @@ void set_current_brush_texture(Brush *br, Tex *newtex) br->mtex.tex = newtex; id_us_plus(&newtex->id); } + BKE_brush_tag_unsaved_changes(br); } Tex *give_current_particle_texture(ParticleSettings *part) diff --git a/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc b/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc index 7ccf7bf2994..dffbbc5b58e 100644 --- a/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc +++ b/source/blender/editors/grease_pencil/intern/grease_pencil_weight_paint.cc @@ -567,6 +567,7 @@ static int toggle_weight_tool_direction(bContext *C, wmOperator * /*op*/) /* Toggle direction flag. */ brush->flag ^= BRUSH_DIR_IN; + BKE_brush_tag_unsaved_changes(brush); /* Update brush settings in UI. */ WM_main_add_notifier(NC_BRUSH | NA_EDITED, nullptr); diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_grease_pencil_color.cc b/source/blender/editors/interface/eyedroppers/eyedropper_grease_pencil_color.cc index 7e4967e2a67..3a038ba6a17 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_grease_pencil_color.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_grease_pencil_color.cc @@ -23,6 +23,7 @@ #include "DNA_material_types.h" #include "DNA_space_types.h" +#include "BKE_brush.hh" #include "BKE_context.hh" #include "BKE_grease_pencil.hh" #include "BKE_lib_id.hh" @@ -292,6 +293,7 @@ static void eyedropper_set_brush_color(bContext *C, const float3 &col_conv) } copy_v3_v3(brush->rgb, col_conv); + BKE_brush_tag_unsaved_changes(brush); } /* Set the material or the palette color. */ diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 79b21ebe5a7..35fc30e2d79 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -6505,6 +6505,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co else if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR) { RNA_property_float_get_array(&but->rnapoin, but->rnaprop, target); } + BKE_brush_tag_unsaved_changes(brush); } else { Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/render/render_update.cc b/source/blender/editors/render/render_update.cc index 236f26a5bba..3f863101bab 100644 --- a/source/blender/editors/render/render_update.cc +++ b/source/blender/editors/render/render_update.cc @@ -27,6 +27,7 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BKE_brush.hh" #include "BKE_context.hh" #include "BKE_icons.h" #include "BKE_main.hh" @@ -337,6 +338,9 @@ void ED_render_id_flush_update(const DEGEditorUpdateContext *update_ctx, ID *id) case ID_SCE: scene_changed(bmain, (Scene *)id); break; + case ID_BR: + BKE_brush_tag_unsaved_changes(reinterpret_cast(id)); + break; default: break; } diff --git a/source/blender/editors/sculpt_paint/brush_asset_ops.cc b/source/blender/editors/sculpt_paint/brush_asset_ops.cc index 224bd48a06b..095a958d74f 100644 --- a/source/blender/editors/sculpt_paint/brush_asset_ops.cc +++ b/source/blender/editors/sculpt_paint/brush_asset_ops.cc @@ -272,6 +272,7 @@ static int brush_asset_save_as_exec(bContext *C, wmOperator *op) brush = reinterpret_cast( bke::asset_edit_id_from_weak_reference(*bmain, ID_BR, brush_asset_reference)); + brush->has_unsaved_changes = false; if (!WM_toolsystem_activate_brush_and_tool(C, paint, brush)) { /* Note brush asset was still saved in editable asset library, so was not a no-op. */ @@ -751,6 +752,7 @@ static int brush_asset_update_exec(bContext *C, wmOperator *op) BLI_assert(ID_IS_ASSET(brush)); bke::asset_edit_id_save(*bmain, brush->id, *op->reports); + brush->has_unsaved_changes = false; refresh_asset_library(C, *user_library); WM_main_add_notifier(NC_ASSET | ND_ASSET_LIST | NA_EDITED, nullptr); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 48c0fa719e5..254f9444f4f 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -1129,6 +1129,7 @@ static int min_distance_edit_modal(bContext *C, wmOperator *op, const wmEvent *e case LEFTMOUSE: { if (event->val == KM_PRESS) { finish(); + BKE_brush_tag_unsaved_changes(op_data.brush); return OPERATOR_FINISHED; } break; diff --git a/source/blender/editors/sculpt_paint/grease_pencil_draw_ops.cc b/source/blender/editors/sculpt_paint/grease_pencil_draw_ops.cc index 2ea0cebe5fe..fd0bbfb4cde 100644 --- a/source/blender/editors/sculpt_paint/grease_pencil_draw_ops.cc +++ b/source/blender/editors/sculpt_paint/grease_pencil_draw_ops.cc @@ -1354,7 +1354,7 @@ static bool grease_pencil_apply_fill(bContext &C, wmOperator &op, const wmEvent GreasePencil &grease_pencil = *static_cast(object.data); auto &op_data = *static_cast(op.customdata); const ToolSettings &ts = *CTX_data_tool_settings(&C); - const Brush &brush = *BKE_paint_brush(&ts.gp_paint->paint); + Brush &brush = *BKE_paint_brush(&ts.gp_paint->paint); const float2 mouse_position = float2(event.mval); const int simplify_levels = brush.gpencil_settings->fill_simplylvl; const std::optional alpha_threshold = @@ -1429,6 +1429,7 @@ static bool grease_pencil_apply_fill(bContext &C, wmOperator &op, const wmEvent /* Save extend value for next operation. */ brush.gpencil_settings->fill_extend_fac = op_data.extension_length; + BKE_brush_tag_unsaved_changes(&brush); return true; } diff --git a/source/blender/editors/sculpt_paint/paint_curve.cc b/source/blender/editors/sculpt_paint/paint_curve.cc index 0c4d9b929f3..f37a4cffe43 100644 --- a/source/blender/editors/sculpt_paint/paint_curve.cc +++ b/source/blender/editors/sculpt_paint/paint_curve.cc @@ -21,6 +21,7 @@ #include "BLT_translation.hh" +#include "BKE_brush.hh" #include "BKE_context.hh" #include "BKE_paint.hh" @@ -152,6 +153,7 @@ static int paintcurve_new_exec(bContext *C, wmOperator * /*op*/) if (brush) { brush->paint_curve = BKE_paint_curve_add(bmain, DATA_("PaintCurve")); + BKE_brush_tag_unsaved_changes(brush); } WM_event_add_notifier(C, NC_PAINTCURVE | NA_ADDED, nullptr); @@ -232,6 +234,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2]) } ED_paintcurve_undo_push_end(C); + BKE_brush_tag_unsaved_changes(br); WM_paint_cursor_tag_redraw(window, region); } @@ -344,6 +347,7 @@ static int paintcurve_delete_point_exec(bContext *C, wmOperator *op) #undef DELETE_TAG ED_paintcurve_undo_push_end(C); + BKE_brush_tag_unsaved_changes(br); WM_paint_cursor_tag_redraw(window, region); @@ -590,6 +594,7 @@ static int paintcurve_slide_invoke(bContext *C, wmOperator *op, const wmEvent *e /* only select the active point */ PAINT_CURVE_POINT_SELECT(pcp, psd->select); BKE_paint_curve_clamp_endpoint_add_index(pc, pcp - pc->points); + BKE_brush_tag_unsaved_changes(br); WM_event_add_modal_handler(C, op); WM_paint_cursor_tag_redraw(window, region); diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index 0a0db55bd26..77856691e0c 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -518,6 +518,7 @@ static void grab_clone_apply(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "delta", delta); add_v2_v2(brush->clone.offset, delta); + BKE_brush_tag_unsaved_changes(brush); ED_region_tag_redraw(CTX_wm_region(C)); } @@ -569,6 +570,7 @@ static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event) RNA_float_set_array(op->ptr, "delta", delta); copy_v2_v2(brush->clone.offset, cmv->startoffset); + BKE_brush_tag_unsaved_changes(brush); grab_clone_apply(C, op); break; @@ -1038,6 +1040,7 @@ static int brush_colors_flip_exec(bContext *C, wmOperator * /*op*/) } else if (br) { swap_v3_v3(br->rgb, br->secondary_rgb); + BKE_brush_tag_unsaved_changes(br); } else { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/sculpt_paint/paint_ops.cc b/source/blender/editors/sculpt_paint/paint_ops.cc index c5b92a31661..2864dc8babb 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_ops.cc @@ -80,6 +80,7 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op) } else { brush->size = max_ii(size, 1); + BKE_brush_tag_unsaved_changes(brush); } } @@ -98,6 +99,7 @@ static int brush_scale_size_exec(bContext *C, wmOperator *op) } else { brush->unprojected_radius = unprojected_radius; + BKE_brush_tag_unsaved_changes(brush); } } @@ -668,6 +670,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] CLAMP(scd->pos_target[1], -scd->dim_target[1] + PIXEL_MARGIN, scd->area_size[1] + scd->dim_target[1] - PIXEL_MARGIN); + BKE_brush_tag_unsaved_changes(scd->br); break; case STENCIL_SCALE: { @@ -684,6 +687,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] } clamp_v2(mdiff, 5.0f, 10000.0f); copy_v2_v2(scd->dim_target, mdiff); + BKE_brush_tag_unsaved_changes(scd->br); break; } case STENCIL_ROTATE: { @@ -698,6 +702,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2] angle -= float(2 * M_PI); } *scd->rot_target = angle; + BKE_brush_tag_unsaved_changes(scd->br); break; } } @@ -860,6 +865,7 @@ static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op) br->stencil_dimension[0] = fabsf(factor * aspx); br->stencil_dimension[1] = fabsf(factor * aspy); } + BKE_brush_tag_unsaved_changes(br); } WM_event_add_notifier(C, NC_WINDOW, nullptr); @@ -917,6 +923,7 @@ static int stencil_reset_transform_exec(bContext *C, wmOperator *op) br->mtex.rot = 0; } + BKE_brush_tag_unsaved_changes(br); WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_FINISHED; diff --git a/source/blender/editors/sculpt_paint/paint_utils.cc b/source/blender/editors/sculpt_paint/paint_utils.cc index 03f8200b27c..f6b992b361e 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.cc +++ b/source/blender/editors/sculpt_paint/paint_utils.cc @@ -526,6 +526,7 @@ static int brush_sculpt_curves_falloff_preset_exec(bContext *C, wmOperator *op) mapping->preset = RNA_enum_get(op->ptr, "shape"); CurveMap *map = mapping->cm; BKE_curvemap_reset(map, &mapping->clipr, mapping->preset, CURVEMAP_SLOPE_POSITIVE); + BKE_brush_tag_unsaved_changes(brush); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.cc b/source/blender/editors/sculpt_paint/sculpt_transform.cc index d3b95b26d99..fe36c780a40 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.cc +++ b/source/blender/editors/sculpt_paint/sculpt_transform.cc @@ -56,7 +56,7 @@ void init_transform(bContext *C, Object &ob, const float mval_fl[2], const char const Scene &scene = *CTX_data_scene(C); const Sculpt &sd = *CTX_data_tool_settings(C)->sculpt; SculptSession &ss = *ob.sculpt; - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ss.init_pivot_pos = ss.pivot_pos; ss.init_pivot_rot = ss.pivot_rot; @@ -66,8 +66,8 @@ void init_transform(bContext *C, Object &ob, const float mval_fl[2], const char ss.prev_pivot_rot = ss.pivot_rot; ss.prev_pivot_scale = ss.pivot_scale; - undo::push_begin_ex(scene, ob, undo_name); BKE_sculpt_update_object_for_edit(depsgraph, &ob, false); + undo::push_begin_ex(scene, ob, undo_name); ss.pivot_rot[3] = 1.0f; diff --git a/source/blender/editors/transform/transform_convert_paintcurve.cc b/source/blender/editors/transform/transform_convert_paintcurve.cc index ea4f4df20ec..b89909cbf80 100644 --- a/source/blender/editors/transform/transform_convert_paintcurve.cc +++ b/source/blender/editors/transform/transform_convert_paintcurve.cc @@ -13,6 +13,7 @@ #include "BLI_math_matrix.h" #include "BLI_math_vector.h" +#include "BKE_brush.hh" #include "BKE_paint.hh" #include "transform.hh" @@ -203,6 +204,12 @@ static void flushTransPaintCurve(TransInfo *t) PaintCurvePoint *pcp = tdpc->pcp; copy_v2_v2(pcp->bez.vec[tdpc->id], td2d->loc); } + + if (t->context) { + Paint *paint = BKE_paint_get_active_from_context(t->context); + Brush *br = (paint) ? BKE_paint_brush(paint) : nullptr; + BKE_brush_tag_unsaved_changes(br); + } } /** \} */ diff --git a/source/blender/editors/transform/transform_generics.cc b/source/blender/editors/transform/transform_generics.cc index 89bdeff534f..98e64d08b71 100644 --- a/source/blender/editors/transform/transform_generics.cc +++ b/source/blender/editors/transform/transform_generics.cc @@ -18,6 +18,7 @@ #include "RNA_access.hh" +#include "BKE_brush.hh" #include "BKE_context.hh" #include "BKE_layer.hh" #include "BKE_mask.h" @@ -1104,6 +1105,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) Brush *br = BKE_paint_brush(paint); PaintCurve *pc = br->paint_curve; copy_v3_v3(r_center, pc->points[pc->add_index - 1].bez.vec[1]); + BKE_brush_tag_unsaved_changes(br); r_center[2] = 0.0f; return true; } diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 686ce4ce355..41c95189864 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -166,6 +166,10 @@ typedef struct BrushCurvesSculptSettings { /** Max number of propagation steps for automasking settings. */ #define AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS 20 +/** + * \note Any change to members that is user visible and that may make the brush differ from the one + * saved in the asset library should be followed by a #BKE_brush_tag_unsaved_changes() call. + */ typedef struct Brush { DNA_DEFINE_CXX_METHODS(Brush) @@ -264,7 +268,11 @@ typedef struct Brush { /** Source for fill brush color gradient application. */ char gradient_fill_mode; - char _pad0; + /** + * Tag to indicate to the user that the brush has been changed since being imported. Only set for + * brushes that are actually imported (must have #ID.lib set). Runtime only. + */ + char has_unsaved_changes; /** Projection shape (sphere, circle). */ char falloff_shape; diff --git a/source/blender/makesrna/intern/rna_brush.cc b/source/blender/makesrna/intern/rna_brush.cc index f35cd095ee4..c92b998e9e8 100644 --- a/source/blender/makesrna/intern/rna_brush.cc +++ b/source/blender/makesrna/intern/rna_brush.cc @@ -714,12 +714,15 @@ static void rna_Brush_reset_icon(Brush *br) static void rna_Brush_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; + BKE_brush_tag_unsaved_changes(br); WM_main_add_notifier(NC_BRUSH | NA_EDITED, br); // WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, nullptr); } -static void rna_Brush_material_update(bContext * /*C*/, PointerRNA * /*ptr*/) +static void rna_Brush_material_update(bContext * /*C*/, PointerRNA *ptr) { + Brush *br = (Brush *)ptr->data; + BKE_brush_tag_unsaved_changes(br); /* number of material users changed */ WM_main_add_notifier(NC_SPACE | ND_SPACE_PROPERTIES, nullptr); } @@ -1025,6 +1028,12 @@ static std::optional rna_BrushGpencilSettings_path(const PointerRNA return "gpencil_settings"; } +static void rna_BrushGpencilSettings_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr) +{ + Brush *br = (Brush *)ptr->owner_id; + BKE_brush_tag_unsaved_changes(br); +} + static void rna_BrushGpencilSettings_use_material_pin_update(bContext *C, PointerRNA *ptr) { const Scene *scene = CTX_data_scene(C); @@ -1041,6 +1050,7 @@ static void rna_BrushGpencilSettings_use_material_pin_update(bContext *C, Pointe BKE_gpencil_brush_material_set(brush, nullptr); } + rna_BrushGpencilSettings_update(CTX_data_main(C), CTX_data_scene(C), ptr); /* number of material users changed */ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_PROPERTIES, nullptr); } @@ -1083,6 +1093,15 @@ static void rna_GPencilBrush_pin_mode_update(bContext *C, PointerRNA *ptr) GP_BRUSH_MODE_MATERIAL; } } + rna_BrushGpencilSettings_update(CTX_data_main(C), CTX_data_scene(C), ptr); +} + +static void rna_BrushCurvesSculptSettings_update(Main * /*bmain*/, + Scene * /*scene*/, + PointerRNA *ptr) +{ + Brush *br = (Brush *)ptr->owner_id; + BKE_brush_tag_unsaved_changes(br); } static const EnumPropertyItem *rna_BrushTextureSlot_map_mode_itemf(bContext *C, @@ -1382,7 +1401,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Strength", "Color strength for new strokes (affect alpha factor of color)"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Jitter factor for new strokes */ prop = RNA_def_property(srna, "pen_jitter", PROP_FLOAT, PROP_FACTOR); @@ -1392,7 +1411,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Jitter", "Jitter factor of brush radius for new strokes"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_BRUSH); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Randomness factor for pressure */ prop = RNA_def_property(srna, "random_pressure", PROP_FLOAT, PROP_FACTOR); @@ -1401,7 +1420,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Pressure Randomness", "Randomness factor for pressure in new strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Randomness factor for strength */ prop = RNA_def_property(srna, "random_strength", PROP_FLOAT, PROP_FACTOR); @@ -1410,7 +1429,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Strength Randomness", "Randomness factor strength in new strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Angle when brush is full size */ prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); @@ -1421,7 +1440,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Direction of the stroke at which brush gives maximal thickness " "(0" BLI_STR_UTF8_DEGREE_SIGN " for horizontal)"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Factor to change brush size depending of angle */ prop = RNA_def_property(srna, "angle_factor", PROP_FLOAT, PROP_FACTOR); @@ -1432,7 +1451,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Angle Factor", "Reduce brush thickness by this factor when stroke is perpendicular to 'Angle' direction"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Smoothing factor for new strokes */ prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE); @@ -1445,7 +1464,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Amount of smoothing to apply after finish newly created strokes, to reduce jitter/noise"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_AMOUNT); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Iterations of the Smoothing factor */ prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE); @@ -1453,7 +1472,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_range(prop, 0, 100); RNA_def_property_ui_text(prop, "Iterations", "Number of times to smooth newly created strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Subdivision level for new strokes */ prop = RNA_def_property(srna, "pen_subdivision_steps", PROP_INT, PROP_NONE); @@ -1464,7 +1483,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Subdivision Steps", "Number of times to subdivide newly created strokes, for less jagged strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Simplify factor */ prop = RNA_def_property(srna, "simplify_factor", PROP_FLOAT, PROP_NONE); @@ -1473,6 +1492,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0, 100.0, 1.0f, 3); RNA_def_property_ui_text(prop, "Simplify", "Factor of Simplify using adaptive algorithm"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "simplify_pixel_threshold", PROP_FLOAT, PROP_PIXEL); RNA_def_property_float_sdna(prop, nullptr, "simplify_px"); @@ -1484,6 +1504,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Threashold in screen space used for the simplify algorithm. Points within this threashold " "are treated as if they were in a straight line."); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Curves for pressure */ prop = RNA_def_property(srna, "curve_sensitivity", PROP_POINTER, PROP_NONE); @@ -1491,63 +1512,63 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Curve Sensitivity", "Curve used for the sensitivity"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_strength", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_strength"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Curve Strength", "Curve used for the strength"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_jitter", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_jitter"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Curve Jitter", "Curve used for the jitter effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_random_pressure", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_rand_pressure"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Random Curve", "Curve used for modulating effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_random_strength", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_rand_strength"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Random Curve", "Curve used for modulating effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_random_uv", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_rand_uv"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Random Curve", "Curve used for modulating effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_random_hue", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_rand_hue"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Random Curve", "Curve used for modulating effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_random_saturation", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_rand_saturation"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Random Curve", "Curve used for modulating effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "curve_random_value", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, nullptr, "curve_rand_value"); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Random Curve", "Curve used for modulating effect"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Fill threshold for transparency. */ prop = RNA_def_property(srna, "fill_threshold", PROP_FLOAT, PROP_FACTOR); @@ -1556,7 +1577,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Threshold", "Threshold to consider color transparent for filling"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* fill factor size */ prop = RNA_def_property(srna, "fill_factor", PROP_FLOAT, PROP_NONE); @@ -1567,7 +1588,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Precision", "Factor for fill boundary accuracy, higher values are more accurate but slower"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* fill simplify steps */ prop = RNA_def_property(srna, "fill_simplify_level", PROP_INT, PROP_NONE); @@ -1576,14 +1597,14 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Simplify", "Number of simplify steps (large values reduce fill accuracy)"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "uv_random", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, nullptr, "uv_random"); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text(prop, "UV Random", "Random factor for auto-generated UV rotation"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* gradient control */ prop = RNA_def_property(srna, "hardness", PROP_FLOAT, PROP_FACTOR); @@ -1595,6 +1616,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Hardness", "Gradient from the center of Dot and Box strokes (set to 1 for a solid stroke)"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* gradient shape ratio */ prop = RNA_def_property(srna, "aspect", PROP_FLOAT, PROP_XYZ); @@ -1604,6 +1626,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Aspect", ""); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "input_samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, nullptr, "input_samples"); @@ -1613,7 +1636,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Input Samples", "Generated intermediate points for very fast mouse movements (Set to 0 to disable)"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* active smooth factor while drawing */ prop = RNA_def_property(srna, "active_smooth_factor", PROP_FLOAT, PROP_FACTOR); @@ -1621,7 +1644,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Active Smooth", "Amount of smoothing while drawing"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "eraser_strength_factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, nullptr, "era_strength_f"); @@ -1629,7 +1652,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0, 100.0, 10, 1); RNA_def_property_ui_text(prop, "Affect Stroke Strength", "Amount of erasing for strength"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "eraser_thickness_factor", PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_sdna(prop, nullptr, "era_thickness_f"); @@ -1637,7 +1660,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0, 100.0, 10, 1); RNA_def_property_ui_text(prop, "Affect Stroke Thickness", "Amount of erasing for thickness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Mode type. */ prop = RNA_def_property(srna, "vertex_mode", PROP_ENUM, PROP_NONE); @@ -1645,6 +1668,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_enum_items(prop, gppaint_mode_types_items); RNA_def_property_ui_text(prop, "Mode Type", "Defines how vertex color affect to the strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Vertex Color mix factor. */ prop = RNA_def_property(srna, "vertex_color_factor", PROP_FLOAT, PROP_FACTOR); @@ -1653,6 +1677,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text( prop, "Vertex Color Factor", "Factor used to mix vertex color to get final color"); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Hue randomness. */ prop = RNA_def_property(srna, "random_hue_factor", PROP_FLOAT, PROP_FACTOR); @@ -1669,6 +1694,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_float_default(prop, 0.0f); RNA_def_property_ui_text(prop, "Saturation", "Random factor to modify original saturation"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Value randomness. */ prop = RNA_def_property(srna, "random_value_factor", PROP_FLOAT, PROP_FACTOR); @@ -1677,6 +1703,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_float_default(prop, 0.0f); RNA_def_property_ui_text(prop, "Value", "Random factor to modify original value"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Factor to extend stroke extremes in Fill brush. */ prop = RNA_def_property(srna, "extend_stroke_factor", PROP_FLOAT, PROP_NONE); @@ -1686,6 +1713,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Closure Size", "Strokes end extension for closing gaps, use zero to disable"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "fill_extend_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "fill_extend_mode"); @@ -1693,6 +1721,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Closure Mode", "Types of stroke extensions used for closing gaps"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Number of pixels to dilate fill area. Negative values contract the filled area. */ prop = RNA_def_property(srna, "dilate", PROP_INT, PROP_PIXEL); @@ -1702,7 +1731,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Dilate/Contract", "Number of pixels to expand or contract fill area"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); /* Factor to determine outline external perimeter thickness. */ prop = RNA_def_property(srna, "outline_thickness_factor", PROP_FLOAT, PROP_FACTOR); @@ -1712,6 +1741,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Thickness", "Thickness of the outline stroke relative to current brush thickness"); RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, ParameterFlag(0)); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); /* Flags */ prop = RNA_def_property(srna, "use_pressure", PROP_BOOLEAN, PROP_NONE); @@ -1719,7 +1749,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use tablet pressure"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_strength_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_USE_STRENGTH_PRESSURE); @@ -1727,98 +1757,98 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Use Pressure Strength", "Use tablet pressure for color strength"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_jitter_pressure", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_USE_JITTER_PRESSURE); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure Jitter", "Use tablet pressure for jitter"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_stroke_random_hue", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_HUE_AT_STROKE); RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0); RNA_def_property_ui_text(prop, "Stroke Random", "Use randomness at stroke level"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_stroke_random_sat", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_SAT_AT_STROKE); RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0); RNA_def_property_ui_text(prop, "Stroke Random", "Use randomness at stroke level"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_stroke_random_val", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_VAL_AT_STROKE); RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0); RNA_def_property_ui_text(prop, "Stroke Random", "Use randomness at stroke level"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_stroke_random_radius", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_PRESS_AT_STROKE); RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0); RNA_def_property_ui_text(prop, "Stroke Random", "Use randomness at stroke level"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_stroke_random_strength", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_STRENGTH_AT_STROKE); RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0); RNA_def_property_ui_text(prop, "Stroke Random", "Use randomness at stroke level"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_stroke_random_uv", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_UV_AT_STROKE); RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0); RNA_def_property_ui_text(prop, "Stroke Random", "Use randomness at stroke level"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_random_press_hue", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_HUE_RAND_PRESS); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use pressure to modulate randomness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_random_press_sat", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_SAT_RAND_PRESS); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use pressure to modulate randomness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_random_press_val", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_VAL_RAND_PRESS); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use pressure to modulate randomness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_random_press_radius", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_PRESSURE_RAND_PRESS); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use pressure to modulate randomness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_random_press_strength", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_STRENGTH_RAND_PRESS); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use pressure to modulate randomness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_random_press_uv", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", GP_BRUSH_USE_UV_RAND_PRESS); RNA_def_property_ui_icon(prop, ICON_STYLUS_PRESSURE, 0); RNA_def_property_ui_text(prop, "Use Pressure", "Use pressure to modulate randomness"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_settings_stabilizer", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_STABILIZE_MOUSE); @@ -1828,6 +1858,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) "Draw lines with a delay to allow smooth strokes (press Shift key to " "override while drawing)"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "eraser_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "eraser_mode"); @@ -1835,7 +1866,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Mode", "Eraser Mode"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, nullptr); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "caps_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "caps_type"); @@ -1843,24 +1874,28 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Caps Type", "The shape of the start and end of the stroke"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "fill_draw_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "fill_draw_mode"); RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_draw_modes_items); RNA_def_property_ui_text(prop, "Mode", "Mode to draw boundary limits"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "fill_layer_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "fill_layer_mode"); RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_layers_modes_items); RNA_def_property_ui_text(prop, "Layer Mode", "Layers used as boundaries"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "fill_direction", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "fill_direction"); RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_direction_items); RNA_def_property_ui_text(prop, "Direction", "Direction of the fill"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "pin_draw_mode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs( @@ -1876,25 +1911,28 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_modes_items); RNA_def_property_ui_text(prop, "Mode", "Preselected mode when using this brush"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_trim", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_TRIM_STROKE); RNA_def_property_boolean_default(prop, false); RNA_def_property_ui_text(prop, "Trim Stroke Ends", "Trim intersecting stroke ends"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_settings_outline", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_OUTLINE_STROKE); RNA_def_property_boolean_default(prop, false); RNA_def_property_ui_text(prop, "Outline", "Convert stroke to outline"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_edit_position", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna( prop, nullptr, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_APPLY_POSITION); RNA_def_property_ui_text(prop, "Affect Position", "The brush affects the position of the point"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_edit_strength", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna( @@ -1902,7 +1940,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Affect Strength", "The brush affects the color strength of the point"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_edit_thickness", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna( @@ -1910,13 +1948,13 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Affect Thickness", "The brush affects the thickness of the point"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_edit_uv", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_APPLY_UV); RNA_def_property_ui_text(prop, "Affect UV", "The brush affects the UV rotation of the point"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_BrushGpencilSettings_update"); /* Material */ prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); @@ -1943,12 +1981,14 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_boolean_default(prop, true); RNA_def_property_ui_text(prop, "Show Lines", "Show help lines for filling to see boundaries"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "show_fill_extend", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_FILL_SHOW_EXTENDLINES); RNA_def_property_boolean_default(prop, true); RNA_def_property_ui_text(prop, "Visual Aids", "Show help lines for stroke extension"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_collide_strokes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_FILL_STROKE_COLLIDE); @@ -1956,6 +1996,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Strokes Collision", "Check if extend lines collide with strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "show_fill", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, nullptr, "flag", GP_BRUSH_FILL_HIDE); @@ -1963,23 +2004,27 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Show Fill", "Show transparent lines to use as boundary for filling"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_fill_limit", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_FILL_FIT_DISABLE); RNA_def_property_boolean_default(prop, true); RNA_def_property_ui_text(prop, "Limit to Viewport", "Fill only visible areas in viewport"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_settings_postprocess", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_GROUP_SETTINGS); RNA_def_property_ui_text( prop, "Use Post-Process Settings", "Additional post processing options for new strokes"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_settings_random", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_GROUP_RANDOM); RNA_def_property_ui_text(prop, "Random Settings", "Random brush settings"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_material_pin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_MATERIAL_PINNED); @@ -1995,22 +2040,26 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Show Lasso", "Do not display fill color while drawing the stroke"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_occlude_eraser", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_OCCLUDE_ERASER); RNA_def_property_ui_text(prop, "Occlude Eraser", "Erase only strokes visible and not occluded"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_keep_caps_eraser", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_ERASER_KEEP_CAPS); RNA_def_property_ui_text( prop, "Keep Caps", "Keep the caps as they are and don't flatten them when erasing"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); prop = RNA_def_property(srna, "use_active_layer_only", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", GP_BRUSH_ACTIVE_LAYER_ONLY); RNA_def_property_ui_text(prop, "Active Layer", "Only edit the active layer of the object"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_BrushGpencilSettings_update"); } static void rna_def_curves_sculpt_options(BlenderRNA *brna) @@ -2046,11 +2095,13 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) prop = RNA_def_property(srna, "add_amount", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 1, INT32_MAX); RNA_def_property_ui_text(prop, "Count", "Number of curves added by the Add brush"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "points_per_curve", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 2, INT32_MAX); RNA_def_property_ui_text( prop, "Points per Curve", "Number of control points in a newly added curve"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "use_uniform_scale", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", BRUSH_CURVES_SCULPT_FLAG_SCALE_UNIFORM); @@ -2058,6 +2109,7 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) "Scale Uniform", "Grow or shrink curves by changing their size uniformly instead of " "using trimming or extrapolation"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "minimum_length", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0.0f, FLT_MAX); @@ -2069,6 +2121,7 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) prop, nullptr, "flag", BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH); RNA_def_property_ui_text( prop, "Interpolate Length", "Use length of the curves in close proximity"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "use_radius_interpolate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna( @@ -2076,6 +2129,7 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) RNA_def_property_boolean_default(prop, true); RNA_def_property_ui_text( prop, "Interpolate Radius", "Use radius of the curves in close proximity"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "use_point_count_interpolate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna( @@ -2083,11 +2137,13 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Interpolate Point Count", "Use the number of points from the curves in close proximity"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "use_shape_interpolate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag", BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE); RNA_def_property_ui_text( prop, "Interpolate Shape", "Use shape of the curves in close proximity"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "curve_length", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0.0, FLT_MAX); @@ -2095,12 +2151,14 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) prop, "Curve Length", "Length of newly added curves when it is not interpolated from other curves"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "minimum_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0.0, 1000.0f, 0.001, 2); RNA_def_property_ui_text( prop, "Minimum Distance", "Goal distance between curve roots for the Density brush"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "curve_radius", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0.0, FLT_MAX); @@ -2110,23 +2168,27 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) prop, "Curve Radius", "Radius of newly added curves when it is not interpolated from other curves"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "density_add_attempts", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 0, INT32_MAX); RNA_def_property_ui_text( prop, "Density Add Attempts", "How many times the Density brush tries to add a new curve"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "density_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, density_mode_items); RNA_def_property_ui_text( prop, "Density Mode", "Determines whether the brush adds or removes curves"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_OPERATOR_DEFAULT); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); prop = RNA_def_property(srna, "curve_parameter_falloff", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "CurveMapping"); RNA_def_property_ui_text(prop, "Curve Parameter Falloff", "Falloff that is applied from the tip to the root of each curve"); + RNA_def_property_update(prop, 0, "rna_BrushCurvesSculptSettings_update"); } static void rna_def_brush(BlenderRNA *brna) @@ -2460,6 +2522,13 @@ static void rna_def_brush(BlenderRNA *brna) srna, "Brush", "Brush data-block for storing brush settings for painting and sculpting"); RNA_def_struct_ui_icon(srna, ICON_BRUSH_DATA); + prop = RNA_def_property(srna, "has_unsaved_changes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, + "Has unsaved changes", + "Indicates that there are any user visible changes since the brush has " + "been imported or read from the file"); + /* enums */ prop = RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_blend_items); @@ -2503,12 +2572,14 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Brush Type", ""); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_BRUSH); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "gpencil_vertex_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "gpencil_vertex_brush_type"); RNA_def_property_enum_items(prop, rna_enum_brush_gpencil_vertex_types_items); RNA_def_property_ui_text(prop, "Brush Type", ""); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "gpencil_sculpt_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "gpencil_sculpt_brush_type"); @@ -2516,12 +2587,14 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Brush Type", ""); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "gpencil_weight_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "gpencil_weight_brush_type"); RNA_def_property_enum_items(prop, rna_enum_brush_gpencil_weight_types_items); RNA_def_property_ui_text(prop, "Brush Type", ""); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "curves_sculpt_tool", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, nullptr, "curves_sculpt_brush_type"); @@ -2529,6 +2602,7 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Brush Type", ""); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVES); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, 0, "rna_Brush_update"); /** End per mode brush type properties. */ @@ -3360,6 +3434,7 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "use_paint_antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "sampling_flag", BRUSH_PAINT_ANTIALIASING); RNA_def_property_ui_text(prop, "Anti-Aliasing", "Smooths the edges of the strokes"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_multiplane_scrape_dynamic", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "flag2", BRUSH_MULTIPLANE_SCRAPE_DYNAMIC); @@ -3642,35 +3717,43 @@ static void rna_def_brush(BlenderRNA *brna) prop = RNA_def_property(srna, "use_paint_sculpt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_SCULPT); RNA_def_property_ui_text(prop, "Use Sculpt", "Use this brush in sculpt mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_paint_uv_sculpt", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_EDIT); RNA_def_property_ui_text(prop, "Use UV Sculpt", "Use this brush in UV sculpt mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_paint_vertex", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_VERTEX_PAINT); RNA_def_property_ui_text(prop, "Use Vertex", "Use this brush in vertex paint mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_paint_weight", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_WEIGHT_PAINT); RNA_def_property_ui_text(prop, "Use Weight", "Use this brush in weight paint mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_paint_image", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_TEXTURE_PAINT); RNA_def_property_ui_text(prop, "Use Texture", "Use this brush in texture paint mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_paint_grease_pencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_PAINT_GREASE_PENCIL); RNA_def_property_ui_text(prop, "Use Paint", "Use this brush in grease pencil drawing mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_vertex_grease_pencil", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_VERTEX_GREASE_PENCIL); RNA_def_property_ui_text( prop, "Use Vertex", "Use this brush in grease pencil vertex color mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); prop = RNA_def_property(srna, "use_paint_sculpt_curves", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, nullptr, "ob_mode", OB_MODE_SCULPT_CURVES); RNA_def_property_ui_text(prop, "Use Sculpt", "Use this brush in sculpt curves mode"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); /* texture */ prop = RNA_def_property(srna, "texture_slot", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_texture.cc b/source/blender/makesrna/intern/rna_texture.cc index 03066f242bb..6d9693e7d03 100644 --- a/source/blender/makesrna/intern/rna_texture.cc +++ b/source/blender/makesrna/intern/rna_texture.cc @@ -134,6 +134,7 @@ static const EnumPropertyItem blend_type_items[] = { # include "RNA_access.hh" +# include "BKE_brush.hh" # include "BKE_colorband.hh" # include "BKE_context.hh" # include "BKE_image.h" @@ -269,6 +270,7 @@ void rna_TextureSlot_update(bContext *C, PointerRNA *ptr) MTex *mtex = static_cast(ptr->data); ViewLayer *view_layer = CTX_data_view_layer(C); BKE_paint_invalidate_overlay_tex(scene, view_layer, mtex->tex); + BKE_brush_tag_unsaved_changes(reinterpret_cast(id)); WM_main_add_notifier(NC_BRUSH, id); break; }