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:
authorBastien Montagne <bastien@blender.org>2020-06-10 17:43:25 +0300
committerBastien Montagne <bastien@blender.org>2020-06-10 17:48:49 +0300
commit74ec37b70cbc8dc228f11d0796dbe68c24526b16 (patch)
tree5691206349ce3365d554ec64e136fc534908af76 /source/blender/blenkernel/intern
parent1d0017089c6ad4bd9b87af1bb30024a86e7b2771 (diff)
Enable (deep) copy of overrides.
This commit enables basic copy of overrides on generic ID level, as well as from (deep) copy operators for objects and collections. So e.g. if your linked overridden caracter is in a collection, you can now (from the outliner) Duplicate that override collection to get a new overriding copy of the character. We still need operators (new or modifying existing ones) to handle that from 3DView e.g. Note that deep copy code for objects/collections (and incidently animdata) had to be modified to avoid duplicating/making local IDs that remain linked ones being used by overrides ones.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/anim_data.c5
-rw-r--r--source/blender/blenkernel/intern/collection.c9
-rw-r--r--source/blender/blenkernel/intern/lib_id.c14
-rw-r--r--source/blender/blenkernel/intern/lib_override.c21
-rw-r--r--source/blender/blenkernel/intern/object.c317
5 files changed, 195 insertions, 171 deletions
diff --git a/source/blender/blenkernel/intern/anim_data.c b/source/blender/blenkernel/intern/anim_data.c
index 9ab4e5c028d..cbb34cbee30 100644
--- a/source/blender/blenkernel/intern/anim_data.c
+++ b/source/blender/blenkernel/intern/anim_data.c
@@ -381,14 +381,15 @@ bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
void BKE_animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid)
{
+ const bool is_id_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
- if (adt->action) {
+ if (adt->action && (!is_id_liboverride || !ID_IS_LINKED(adt->action))) {
id_us_min((ID *)adt->action);
adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(bmain, adt->action)) :
BKE_action_copy(bmain, adt->action);
}
- if (adt->tmpact) {
+ if (adt->tmpact && (!is_id_liboverride || !ID_IS_LINKED(adt->tmpact))) {
id_us_min((ID *)adt->tmpact);
adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(bmain, adt->tmpact)) :
BKE_action_copy(bmain, adt->tmpact);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index e8e3e61ced4..1388146eeb7 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -314,6 +314,7 @@ static Collection *collection_duplicate_recursive(Main *bmain,
Collection *collection_new;
bool do_full_process = false;
const int object_dupflag = (do_obdata) ? U.dupflag : 0;
+ const bool is_collection_liboverride = ID_IS_OVERRIDE_LIBRARY(collection_old);
if (!do_hierarchy || collection_old->id.newid == NULL) {
BKE_id_copy(bmain, &collection_old->id, (ID **)&collection_new);
@@ -359,6 +360,12 @@ static Collection *collection_duplicate_recursive(Main *bmain,
Object *ob_old = cob->ob;
Object *ob_new = (Object *)ob_old->id.newid;
+ /* If collection is an override, we do not want to duplicate any linked data-block, as that
+ * would generate a purely local data. */
+ if (is_collection_liboverride && ID_IS_LINKED(ob_old)) {
+ continue;
+ }
+
if (ob_new == NULL) {
ob_new = BKE_object_duplicate(bmain, ob_old, object_dupflag);
ID_NEW_SET(ob_old, ob_new);
@@ -430,7 +437,7 @@ Collection *BKE_collection_duplicate(Main *bmain,
Collection *collection_new = collection_duplicate_recursive(
bmain, parent, collection, do_hierarchy, do_objects, do_obdata);
- /* This code will follows into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
BKE_libblock_relink_to_newid(&collection_new->id);
if (do_hierarchy) {
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index 734fe9ad9ae..3ad429c5f5a 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -64,6 +64,7 @@
#include "BKE_idtype.h"
#include "BKE_key.h"
#include "BKE_lib_id.h"
+#include "BKE_lib_override.h"
#include "BKE_lib_query.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
@@ -1153,14 +1154,13 @@ void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int ori
new_id->properties = IDP_CopyProperty_ex(id->properties, copy_data_flag);
}
- /* XXX Again... We need a way to control what we copy in a much more refined way.
- * We cannot always copy this, some internal copying will die on it! */
- /* For now, upper level code will have to do that itself when required. */
-#if 0
- if (id->override != NULL) {
- BKE_override_copy(new_id, id);
+ /* We may need our own flag to control that at some point, but for now 'no main' one should be
+ * good enough. */
+ if ((orig_flag & LIB_ID_CREATE_NO_MAIN) == 0 && id->override_library != NULL) {
+ /* We do not want to copy existing override rules here, as they would break the proper
+ * remapping between IDs. Proper overrides rules will be re-generated anyway. */
+ BKE_lib_override_library_copy(new_id, id, false);
}
-#endif
if (id_can_have_animdata(new_id)) {
IdAdtTemplate *iat = (IdAdtTemplate *)new_id;
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 8d1a4e3594c..d16428ccd60 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -92,7 +92,7 @@ IDOverrideLibrary *BKE_lib_override_library_init(ID *local_id, ID *reference_id)
if (ancestor_id != NULL && ancestor_id->override_library != NULL) {
/* Original ID has a template, use it! */
- BKE_lib_override_library_copy(local_id, ancestor_id);
+ BKE_lib_override_library_copy(local_id, ancestor_id, true);
if (local_id->override_library->reference != reference_id) {
id_us_min(local_id->override_library->reference);
local_id->override_library->reference = reference_id;
@@ -110,8 +110,8 @@ IDOverrideLibrary *BKE_lib_override_library_init(ID *local_id, ID *reference_id)
return local_id->override_library;
}
-/** Deep copy of a whole override from \a src_id to \a dst_id. */
-void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id)
+/** Shalow or deep copy of a whole override from \a src_id to \a dst_id. */
+void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_full_copy)
{
BLI_assert(src_id->override_library != NULL);
@@ -138,12 +138,15 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id)
(ID *)src_id;
id_us_plus(dst_id->override_library->reference);
- BLI_duplicatelist(&dst_id->override_library->properties, &src_id->override_library->properties);
- for (IDOverrideLibraryProperty *op_dst = dst_id->override_library->properties.first,
- *op_src = src_id->override_library->properties.first;
- op_dst;
- op_dst = op_dst->next, op_src = op_src->next) {
- lib_override_library_property_copy(op_dst, op_src);
+ if (do_full_copy) {
+ BLI_duplicatelist(&dst_id->override_library->properties,
+ &src_id->override_library->properties);
+ for (IDOverrideLibraryProperty *op_dst = dst_id->override_library->properties.first,
+ *op_src = src_id->override_library->properties.first;
+ op_dst;
+ op_dst = op_dst->next, op_src = op_src->next) {
+ lib_override_library_property_copy(op_dst, op_src);
+ }
}
dst_id->tag &= ~LIB_TAG_OVERRIDE_LIBRARY_REFOK;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 4505f9e8d57..127c5243c7e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1763,6 +1763,8 @@ Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
Material ***matarar;
ID *id;
int a, didit;
+ const bool is_object_liboverride = ID_IS_OVERRIDE_LIBRARY(ob);
+
Object *obn = BKE_object_copy(bmain, ob);
/* 0 == full linked. */
@@ -1790,6 +1792,9 @@ Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
for (a = 0; a < obn->totcol; a++) {
id = (ID *)obn->mat[a];
if (id) {
+ if (is_object_liboverride && ID_IS_LINKED(id)) {
+ continue;
+ }
ID_NEW_REMAP_US(obn->mat[a])
else
{
@@ -1807,6 +1812,9 @@ Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
for (psys = obn->particlesystem.first; psys; psys = psys->next) {
id = (ID *)psys->part;
if (id) {
+ if (is_object_liboverride && ID_IS_LINKED(id)) {
+ continue;
+ }
ID_NEW_REMAP_US(psys->part)
else
{
@@ -1823,179 +1831,181 @@ Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
id = obn->data;
didit = 0;
- switch (obn->type) {
- case OB_MESH:
- if (dupflag & USER_DUP_MESH) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
- didit = 1;
+ if (!is_object_liboverride || !ID_IS_LINKED(id)) {
+ switch (obn->type) {
+ case OB_MESH:
+ if (dupflag & USER_DUP_MESH) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_CURVE:
- if (dupflag & USER_DUP_CURVE) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_CURVE:
+ if (dupflag & USER_DUP_CURVE) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_SURF:
- if (dupflag & USER_DUP_SURF) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_SURF:
+ if (dupflag & USER_DUP_SURF) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_FONT:
- if (dupflag & USER_DUP_FONT) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_FONT:
+ if (dupflag & USER_DUP_FONT) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_MBALL:
- if (dupflag & USER_DUP_MBALL) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_MBALL:
+ if (dupflag & USER_DUP_MBALL) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_LAMP:
- if (dupflag & USER_DUP_LAMP) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_light_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_LAMP:
+ if (dupflag & USER_DUP_LAMP) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_light_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_ARMATURE:
- if (dupflag != 0) {
- DEG_id_tag_update(&obn->id, ID_RECALC_GEOMETRY);
- if (obn->pose) {
- BKE_pose_tag_recalc(bmain, obn->pose);
+ break;
+ case OB_ARMATURE:
+ if (dupflag != 0) {
+ DEG_id_tag_update(&obn->id, ID_RECALC_GEOMETRY);
+ if (obn->pose) {
+ BKE_pose_tag_recalc(bmain, obn->pose);
+ }
+ if (dupflag & USER_DUP_ARM) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
+ BKE_pose_rebuild(bmain, obn, obn->data, true);
+ didit = 1;
+ }
+ id_us_min(id);
+ }
}
- if (dupflag & USER_DUP_ARM) {
+ break;
+ case OB_LATTICE:
+ if (dupflag != 0) {
ID_NEW_REMAP_US2(obn->data)
else
{
- obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
- BKE_pose_rebuild(bmain, obn, obn->data, true);
+ obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
}
- }
- break;
- case OB_LATTICE:
- if (dupflag != 0) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
- didit = 1;
- }
- id_us_min(id);
- }
- break;
- case OB_CAMERA:
- if (dupflag != 0) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_CAMERA:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_LIGHTPROBE:
- if (dupflag & USER_DUP_LIGHTPROBE) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_lightprobe_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_LIGHTPROBE:
+ if (dupflag & USER_DUP_LIGHTPROBE) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_lightprobe_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_SPEAKER:
- if (dupflag != 0) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_SPEAKER:
+ if (dupflag != 0) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_GPENCIL:
- if (dupflag & USER_DUP_GPENCIL) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_GPENCIL:
+ if (dupflag & USER_DUP_GPENCIL) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_gpencil_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_HAIR:
- if (dupflag & USER_DUP_HAIR) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_hair_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_HAIR:
+ if (dupflag & USER_DUP_HAIR) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_hair_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_POINTCLOUD:
- if (dupflag & USER_DUP_POINTCLOUD) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_pointcloud_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_POINTCLOUD:
+ if (dupflag & USER_DUP_POINTCLOUD) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_pointcloud_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
- case OB_VOLUME:
- if (dupflag & USER_DUP_VOLUME) {
- ID_NEW_REMAP_US2(obn->data)
- else
- {
- obn->data = ID_NEW_SET(obn->data, BKE_volume_copy(bmain, obn->data));
- didit = 1;
+ break;
+ case OB_VOLUME:
+ if (dupflag & USER_DUP_VOLUME) {
+ ID_NEW_REMAP_US2(obn->data)
+ else
+ {
+ obn->data = ID_NEW_SET(obn->data, BKE_volume_copy(bmain, obn->data));
+ didit = 1;
+ }
+ id_us_min(id);
}
- id_us_min(id);
- }
- break;
+ break;
+ }
}
/* Check if obdata is copied. */
@@ -2020,6 +2030,9 @@ Object *BKE_object_duplicate(Main *bmain, const Object *ob, const int dupflag)
for (a = 0; a < obn->totcol; a++) {
id = (ID *)(*matarar)[a];
if (id) {
+ if (is_object_liboverride && ID_IS_LINKED(id)) {
+ continue;
+ }
ID_NEW_REMAP_US((*matarar)[a])
else
{