[Bf-blender-cvs] [13f591d400e] master: ID Duplicate: Factorize a lot the code.

Bastien Montagne noreply at git.blender.org
Wed Jun 17 17:09:16 CEST 2020


Commit: 13f591d400e2d17633bf7ebba9c7890fd563e4d2
Author: Bastien Montagne
Date:   Wed Jun 17 17:01:21 2020 +0200
Branches: master
https://developer.blender.org/rB13f591d400e2d17633bf7ebba9c7890fd563e4d2

ID Duplicate: Factorize a lot the code.

Now that we have a uniform consistent behavior in all our ID duplicate
funtions, we can easily factorize it greatly. Code gets cleaner,
smaller, and less error-prone.

Note that ultimately, this duplicate/deep copy behavior could be added
as a callback of IDTypeInfo.
We could also rethink the duplicate flags (some data, even some obdata,
like Lattice, are not coverred currently).
And so on. But at least code should now be much more easily maintainable
and extendable.

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

M	source/blender/blenkernel/BKE_lib_id.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/lib_id.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/scene.c

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

diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index 8ee5562baae..e6a711732c9 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -227,6 +227,10 @@ bool id_single_user(struct bContext *C,
 bool BKE_id_copy_is_allowed(const struct ID *id);
 bool BKE_id_copy(struct Main *bmain, const struct ID *id, struct ID **newid);
 bool BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
+struct ID *BKE_id_copy_for_duplicate(struct Main *bmain,
+                                     struct ID *id,
+                                     const bool is_owner_id_liboverride,
+                                     const uint duplicate_flags);
 
 void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b);
 void BKE_lib_id_swap_full(struct Main *bmain, struct ID *id_a, struct ID *id_b);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index f115b9e8b7b..dddbf7d45b2 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -345,17 +345,8 @@ static Collection *collection_duplicate_recursive(Main *bmain,
     do_full_process = true;
   }
   else if (collection_old->id.newid == NULL) {
-    BKE_id_copy(bmain, &collection_old->id, (ID **)&collection_new);
-
-    /* Copying add one user by default, need to get rid of that one. */
-    id_us_min(&collection_new->id);
-
-    ID_NEW_SET(collection_old, collection_new);
-
-    if (duplicate_flags & USER_DUP_ACT) {
-      BKE_animdata_copy_id_action(bmain, &collection_new->id, true);
-    }
-
+    collection_new = (Collection *)BKE_id_copy_for_duplicate(
+        bmain, (ID *)collection_old, is_collection_liboverride, duplicate_flags);
     do_full_process = true;
   }
   else {
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index ab9b11f436a..4d36530fccc 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -607,6 +607,49 @@ bool BKE_id_copy(Main *bmain, const ID *id, ID **newid)
   return BKE_id_copy_ex(bmain, id, newid, LIB_ID_COPY_DEFAULT);
 }
 
+/**
+ * Invokes the appropriate copy method for the block and returns the result in
+ * newid, unless test. Returns true if the block can be copied.
+ */
+ID *BKE_id_copy_for_duplicate(Main *bmain,
+                              ID *id,
+                              const bool is_owner_id_liboverride,
+                              const eDupli_ID_Flags duplicate_flags)
+{
+  if (id == NULL) {
+    return NULL;
+  }
+  if (id->newid == NULL) {
+    if (!is_owner_id_liboverride || !ID_IS_LINKED(id)) {
+      ID *id_new;
+      BKE_id_copy(bmain, id, &id_new);
+      /* Copying add one user by default, need to get rid of that one. */
+      id_us_min(id_new);
+      ID_NEW_SET(id, id_new);
+
+      /* Shape keys are always copied with their owner ID, by default. */
+      ID *key_new = (ID *)BKE_key_from_id(id_new);
+      ID *key = (ID *)BKE_key_from_id(id);
+      if (key != NULL) {
+        ID_NEW_SET(key, key_new);
+      }
+
+      /* Note: embedded data (root nodetrees and master collections) should never be referenced by
+       * anything else, so we do not need to set their newid pointer and flag. */
+
+      if (duplicate_flags & USER_DUP_ACT) {
+        BKE_animdata_copy_id_action(bmain, id_new, true);
+        if (key_new != NULL) {
+          BKE_animdata_copy_id_action(bmain, key_new, true);
+        }
+        /* Note that actions of embedded data (root nodetrees and master collections) are handled
+         * by `BKE_animdata_copy_id_action` as well. */
+      }
+    }
+  }
+  return id->newid;
+}
+
 /**
  * Does a mere memory swap over the whole IDs data (including type-specific memory).
  * \note Most internal ID data itself is not swapped (only IDProperties are).
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 28f7a9f12d0..7385fbf3f33 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1771,8 +1771,6 @@ Object *BKE_object_duplicate(Main *bmain,
   }
 
   Material ***matarar;
-  ID *id, *id_new = NULL;
-  int a;
   const bool is_object_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
 
   Object *obn;
@@ -1793,203 +1791,106 @@ Object *BKE_object_duplicate(Main *bmain,
   }
 
   if (dupflag & USER_DUP_MAT) {
-    for (a = 0; a < obn->totcol; a++) {
-      id = (ID *)obn->mat[a];
-      if (id && id->newid == NULL) {
-        if (is_object_liboverride && ID_IS_LINKED(id)) {
-          continue;
-        }
-        BKE_id_copy_ex(bmain, id, &id_new, 0);
-        id_us_min(id_new);
-        ID_NEW_SET(id, id_new);
-        if (dupflag & USER_DUP_ACT) {
-          BKE_animdata_copy_id_action(bmain, id_new, true);
-        }
-      }
+    for (int i = 0; i < obn->totcol; i++) {
+      BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], is_object_liboverride, dupflag);
     }
   }
   if (dupflag & USER_DUP_PSYS) {
     ParticleSystem *psys;
     for (psys = obn->particlesystem.first; psys; psys = psys->next) {
-      id = (ID *)psys->part;
-      if (id && id->newid == NULL) {
-        if (is_object_liboverride && ID_IS_LINKED(id)) {
-          continue;
-        }
-        BKE_id_copy_ex(bmain, id, &id_new, 0);
-        id_us_min(id_new);
-        ID_NEW_SET(id, id_new);
-        if (dupflag & USER_DUP_ACT) {
-          BKE_animdata_copy_id_action(bmain, id_new, true);
-        }
-      }
+      BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, is_object_liboverride, dupflag);
     }
   }
 
-  id = obn->data;
-  bool duplicated_obdata = false;
+  ID *id = obn->data;
+  ID *id_new = NULL;
+  const bool need_to_duplicate_obdata = (id->newid == NULL);
 
-  if (id && id->newid == NULL) {
-    if (!is_object_liboverride || !ID_IS_LINKED(id)) {
-      switch (obn->type) {
-        case OB_MESH:
-          if (dupflag & USER_DUP_MESH) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_CURVE:
-          if (dupflag & USER_DUP_CURVE) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_SURF:
-          if (dupflag & USER_DUP_SURF) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_FONT:
-          if (dupflag & USER_DUP_FONT) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_MBALL:
-          if (dupflag & USER_DUP_MBALL) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_LAMP:
-          if (dupflag & USER_DUP_LAMP) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_ARMATURE:
-          if (dupflag & USER_DUP_ARM) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_LATTICE:
-          if (dupflag != 0) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_CAMERA:
-          if (dupflag != 0) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_LIGHTPROBE:
-          if (dupflag & USER_DUP_LIGHTPROBE) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_SPEAKER:
-          if (dupflag != 0) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_GPENCIL:
-          if (dupflag & USER_DUP_GPENCIL) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_HAIR:
-          if (dupflag & USER_DUP_HAIR) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_POINTCLOUD:
-          if (dupflag & USER_DUP_POINTCLOUD) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
-        case OB_VOLUME:
-          if (dupflag & USER_DUP_VOLUME) {
-            BKE_id_copy(bmain, id, &id_new);
-            id_us_min(id_new);
-            ID_NEW_SET(id, id_new);
-            duplicated_obdata = true;
-          }
-          break;
+  switch (obn->type) {
+    case OB_MESH:
+      if (dupflag & USER_DUP_MESH) {
+        id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag);
       }
-    }
-  }
-
-  /* Check if obdata is copied. */
-  if (duplicated_obdata) {
-    BLI_assert(id_new != NULL);
-
-    Key *key = BKE_key_from_object(obn);
-
-    Key *oldkey = BKE_key_from_object(ob);
-    if (oldkey != NULL) {
-      ID_NEW_SET(oldkey, key);
-    }
-
-    if (

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list