From 35f34a3cf840852b70c1be5910be5517265d96cc Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Wed, 30 Mar 2022 11:06:10 +0200 Subject: Modifiers: Support applying modifiers for multi-user data The current behaviour is to prevent multi-user data from having its modifier applied. Instead, with this patch, we now warn the user that if they want to proceed the object will be made single-user. Note that this only makes the object data single-user. Not the material or actions. As a future step we can apply the same behaviour for the Grease Pencil modifiers Differential Revision: https://developer.blender.org/D14381 --- source/blender/editors/object/object_modifier.c | 41 ++++++++++++++++++------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'source/blender/editors/object/object_modifier.c') diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 0e09fbb7ea4..545265b18b1 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1363,7 +1363,7 @@ void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot) /** \name Apply Modifier Operator * \{ */ -static bool modifier_apply_poll_ex(bContext *C, bool allow_shared) +static bool modifier_apply_poll(bContext *C) { if (!edit_modifier_poll_generic(C, &RNA_Modifier, 0, false, false)) { return false; @@ -1378,10 +1378,6 @@ static bool modifier_apply_poll_ex(bContext *C, bool allow_shared) CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied on override data"); return false; } - if (!allow_shared && (ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) { - CTX_wm_operator_poll_msg_set(C, "Modifiers cannot be applied to multi-user data"); - return false; - } if (md != NULL) { if ((ob->mode & OB_MODE_SCULPT) && (find_multires_modifier_before(scene, md)) && (BKE_modifier_is_same_topology(md) == false)) { @@ -1393,11 +1389,6 @@ static bool modifier_apply_poll_ex(bContext *C, bool allow_shared) return true; } -static bool modifier_apply_poll(bContext *C) -{ - return modifier_apply_poll_ex(C, false); -} - static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, bool keep_modifier) { Main *bmain = CTX_data_main(C); @@ -1406,11 +1397,19 @@ static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, boo Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); const bool do_report = RNA_boolean_get(op->ptr, "report"); + const bool do_single_user = RNA_boolean_get(op->ptr, "single_user"); if (md == NULL) { return OPERATOR_CANCELLED; } + if (do_single_user && ID_REAL_USERS(ob->data) > 1) { + ED_object_single_obdata_user(bmain, scene, ob); + BKE_main_id_newptr_and_tag_clear(bmain); + WM_event_add_notifier(C, NC_WINDOW, NULL); + DEG_relations_tag_update(bmain); + } + int reports_len; char name[MAX_NAME]; if (do_report) { @@ -1447,6 +1446,19 @@ static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *eve { int retval; if (edit_modifier_invoke_properties_with_hover(C, op, event, &retval)) { + PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_Modifier); + Object *ob = (ptr.owner_id != NULL) ? (Object *)ptr.owner_id : ED_object_active_context(C); + + if ((ob->data != NULL) && ID_REAL_USERS(ob->data) > 1) { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "single_user"); + if (!RNA_property_is_set(op->ptr, prop)) { + RNA_property_boolean_set(op->ptr, prop, true); + } + if (RNA_property_boolean_get(op->ptr, prop)) { + return WM_operator_confirm_message( + C, op, "Make object data single-user and apply modifier"); + } + } return modifier_apply_exec(C, op); } return retval; @@ -1467,6 +1479,13 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) edit_modifier_properties(ot); edit_modifier_report_property(ot); + + PropertyRNA *prop = RNA_def_boolean(ot->srna, + "single_user", + false, + "Make Data Single User", + "Make the object's data single user if needed"); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } /** \} */ @@ -1477,7 +1496,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) static bool modifier_apply_as_shapekey_poll(bContext *C) { - return modifier_apply_poll_ex(C, true); + return modifier_apply_poll(C); } static int modifier_apply_as_shapekey_exec(bContext *C, wmOperator *op) -- cgit v1.2.3