Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDalai Felinto <dalai@blender.org>2022-03-30 12:06:10 +0300
committerDalai Felinto <dalai@blender.org>2022-03-30 12:06:10 +0300
commit35f34a3cf840852b70c1be5910be5517265d96cc (patch)
tree85feca0e8d12261484df49dde2f0db621cdc5971
parent218bcff32db55874ccc35300ddd21baa585350dd (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.h2
-rw-r--r--source/blender/editors/object/object_modifier.c41
-rw-r--r--source/blender/editors/object/object_relations.c13
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)
{