[Bf-blender-cvs] [35f34a3cf84] master: Modifiers: Support applying modifiers for multi-user data

Dalai Felinto noreply at git.blender.org
Wed Mar 30 11:12:01 CEST 2022


Commit: 35f34a3cf840852b70c1be5910be5517265d96cc
Author: Dalai Felinto
Date:   Wed Mar 30 11:06:10 2022 +0200
Branches: master
https://developer.blender.org/rB35f34a3cf840852b70c1be5910be5517265d96cc

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

===================================================================

M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_relations.c

===================================================================

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)
 {



More information about the Bf-blender-cvs mailing list