diff options
author | Bastien Montagne <bastien@blender.org> | 2020-07-09 16:33:34 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-07-09 18:56:05 +0300 |
commit | 7b1c406b5431ce65d84ddb5f2c53977c25c18373 (patch) | |
tree | d10874f81e0ca717dc288ae2071bc127c6da990a /source/blender/blenkernel/intern/object.c | |
parent | 78b629a98f0c7c5c2c8f3b6b6d1081646cbe6fde (diff) |
Implement T77959: Never duplicate linked data during deep-copy.
Note that this behavior is enforced on user level for now, but on code
side it is controlled with a flag, which should make it easy to refine
that behavior if needed.
Only exception is when we duplicate a linked ID directly (then we assume
user wants a local deep-copy of that linked data, and we always also
duplicate linked sub-data-blocks).
Note that this commit also slightly refactor the handling of actions of
animdata, by simplifying `BKE_animdata_copy_id_action()` and adding an
explicit new `BKE_animdata_duplicate_id_action()` to be used during ID
duplication (deep copy).
This also allows us to get rid of the special case for liboverrides.
Diffstat (limited to 'source/blender/blenkernel/intern/object.c')
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 55 |
1 files changed, 28 insertions, 27 deletions
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 6331f87f09f..d48ea33cc65 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1760,7 +1760,7 @@ Object *BKE_object_copy(Main *bmain, const Object *ob) */ Object *BKE_object_duplicate(Main *bmain, Object *ob, - const eDupli_ID_Flags dupflag, + eDupli_ID_Flags dupflag, const eLibIDDuplicateFlags duplicate_options) { const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0; @@ -1768,10 +1768,14 @@ Object *BKE_object_duplicate(Main *bmain, if (!is_subprocess) { BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false); BKE_main_id_clear_newpoins(bmain); + /* In case root duplicated ID is linked, assume we want to get a local copy of it and duplicate + * all expected linked data. */ + if (ID_IS_LINKED(ob)) { + dupflag |= USER_DUP_LINKED_ID; + } } Material ***matarar; - const bool is_object_liboverride = ID_IS_OVERRIDE_LIBRARY(ob); Object *obn; BKE_id_copy(bmain, &ob->id, (ID **)&obn); @@ -1785,112 +1789,109 @@ Object *BKE_object_duplicate(Main *bmain, return obn; } - /* duplicates using userflags */ - if (dupflag & USER_DUP_ACT) { - BKE_animdata_copy_id_action(bmain, &obn->id, true); - } + BKE_animdata_duplicate_id_action(bmain, &obn->id, dupflag); if (dupflag & USER_DUP_MAT) { for (int i = 0; i < obn->totcol; i++) { - BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], is_object_liboverride, dupflag); + BKE_id_copy_for_duplicate(bmain, (ID *)obn->mat[i], dupflag); } } if (dupflag & USER_DUP_PSYS) { ParticleSystem *psys; for (psys = obn->particlesystem.first; psys; psys = psys->next) { - BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, is_object_liboverride, dupflag); + BKE_id_copy_for_duplicate(bmain, (ID *)psys->part, dupflag); } } - ID *id = obn->data; + ID *id_old = obn->data; ID *id_new = NULL; - const bool need_to_duplicate_obdata = (id != NULL) && (id->newid == NULL); + const bool need_to_duplicate_obdata = (id_old != NULL) && (id_old->newid == NULL); switch (obn->type) { case OB_MESH: if (dupflag & USER_DUP_MESH) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_CURVE: if (dupflag & USER_DUP_CURVE) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_SURF: if (dupflag & USER_DUP_SURF) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_FONT: if (dupflag & USER_DUP_FONT) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_MBALL: if (dupflag & USER_DUP_MBALL) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_LAMP: if (dupflag & USER_DUP_LAMP) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_ARMATURE: if (dupflag & USER_DUP_ARM) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_LATTICE: if (dupflag != 0) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_CAMERA: if (dupflag != 0) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_LIGHTPROBE: if (dupflag & USER_DUP_LIGHTPROBE) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_SPEAKER: if (dupflag != 0) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_GPENCIL: if (dupflag & USER_DUP_GPENCIL) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_HAIR: if (dupflag & USER_DUP_HAIR) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_POINTCLOUD: if (dupflag & USER_DUP_POINTCLOUD) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; case OB_VOLUME: if (dupflag & USER_DUP_VOLUME) { - id_new = BKE_id_copy_for_duplicate(bmain, id, is_object_liboverride, dupflag); + id_new = BKE_id_copy_for_duplicate(bmain, id_old, dupflag); } break; } /* If obdata has been copied, we may also have to duplicate the materials assigned to it. */ - if (need_to_duplicate_obdata && id_new != NULL) { + if (need_to_duplicate_obdata && !ELEM(id_new, NULL, id_old)) { if (dupflag & USER_DUP_MAT) { matarar = BKE_object_material_array_p(obn); if (matarar) { for (int i = 0; i < obn->totcol; i++) { - BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], is_object_liboverride, dupflag); + BKE_id_copy_for_duplicate(bmain, (ID *)(*matarar)[i], dupflag); } } } |