diff options
author | Dalai Felinto <dalai@blender.org> | 2022-03-30 12:06:10 +0300 |
---|---|---|
committer | Dalai Felinto <dalai@blender.org> | 2022-03-30 12:06:10 +0300 |
commit | 35f34a3cf840852b70c1be5910be5517265d96cc (patch) | |
tree | 85feca0e8d12261484df49dde2f0db621cdc5971 | |
parent | 218bcff32db55874ccc35300ddd21baa585350dd (diff) |
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
-rw-r--r-- | source/blender/editors/include/ED_object.h | 2 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 41 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 13 |
3 files changed, 45 insertions, 11 deletions
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index abadbe5a5c6..54e434e0db5 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -381,6 +381,8 @@ struct Object *ED_object_add_type(struct bContext *C, */ void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Object *ob); +void ED_object_single_obdata_user(struct Main *bmain, struct Scene *scene, struct Object *ob); + /* object motion paths */ /** 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) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 064a84cdea5..7be46bdb24b 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1893,6 +1893,19 @@ static void single_obdata_users( } } +void ED_object_single_obdata_user(Main *bmain, Scene *scene, Object *ob) +{ + FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) { + ob_iter->flag &= ~OB_DONE; + } + FOREACH_SCENE_OBJECT_END; + + /* Tag only the one object. */ + ob->flag |= OB_DONE; + + single_obdata_users(bmain, scene, NULL, NULL, OB_DONE); +} + static void single_object_action_users( Main *bmain, Scene *scene, ViewLayer *view_layer, View3D *v3d, const int flag) { |