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-17 16:02:04 +0300
committerBastien Montagne <bastien@blender.org>2020-06-17 18:06:05 +0300
commitad6cccf058d0296a8741a6583d12967366a31705 (patch)
tree3d931739079db956d02774ac5acc63bb6516d3e9 /source/blender/blenkernel/intern/scene.c
parent514f80b0c4f6375d1a01db1f2e32b495c23c17ca (diff)
Refactor duplicate of data-blocks.
Main change from user side, besides that all pointers should now be properly remapped to new IDs, is that linked objects are no longer preserved when doing a full copy of scenes. Will open a task to check whether we actually still want that behavior (and re-code it in a more correct way then). This is the main part of work done here, it aims at uniformizing and sanitizing that 'deep copy' process for supported IDs (currently scenes, collections and objects). Note that there will be more follow up commits after that one, but this should be the most risky and changing one.
Diffstat (limited to 'source/blender/blenkernel/intern/scene.c')
-rw-r--r--source/blender/blenkernel/intern/scene.c68
1 files changed, 53 insertions, 15 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d3f1efb5975..8e1800ad122 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -829,41 +829,79 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
/* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
if (type == SCE_COPY_FULL) {
+ /* Scene duplication is always root of duplication currently. */
+ const bool is_subprocess = false;
+ ID *id, *id_new;
+
+ if (!is_subprocess) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
+ BKE_main_id_clear_newpoins(bmain);
+ }
+
/* Copy Freestyle LineStyle datablocks. */
LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
LISTBASE_FOREACH (
FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
- if (lineset->linestyle) {
- if (is_scene_liboverride && ID_IS_LINKED(lineset->linestyle)) {
+ id = &lineset->linestyle->id;
+ if (id && id->newid == NULL) {
+ if (is_scene_liboverride && ID_IS_LINKED(id)) {
continue;
}
- id_us_min(&lineset->linestyle->id);
- BKE_id_copy_ex(
- bmain, (ID *)lineset->linestyle, (ID **)&lineset->linestyle, LIB_ID_COPY_ACTIONS);
+ BKE_id_copy_ex(bmain, id, &id_new, LIB_ID_COPY_ACTIONS);
+ id_us_min(id_new);
+ ID_NEW_SET(id, id_new);
}
}
}
/* Full copy of world (included animations) */
- if (sce_copy->world) {
- if (!is_scene_liboverride || !ID_IS_LINKED(sce_copy->world)) {
- id_us_min(&sce_copy->world->id);
- BKE_id_copy_ex(
- bmain, (ID *)sce_copy->world, (ID **)&sce_copy->world, LIB_ID_COPY_ACTIONS);
+ id = &sce->world->id;
+ if (id && id->newid == NULL) {
+ if (!is_scene_liboverride || !ID_IS_LINKED(id)) {
+ BKE_id_copy_ex(bmain, id, &id_new, LIB_ID_COPY_ACTIONS);
+ id_us_min(id_new);
+ ID_NEW_SET(id, id_new);
}
}
/* Full copy of GreasePencil. */
- if (sce_copy->gpd) {
- if (!is_scene_liboverride || !ID_IS_LINKED(sce_copy->gpd)) {
- id_us_min(&sce_copy->gpd->id);
- BKE_id_copy_ex(bmain, (ID *)sce_copy->gpd, (ID **)&sce_copy->gpd, LIB_ID_COPY_ACTIONS);
+ id = &sce->gpd->id;
+ if (id && id->newid == NULL) {
+ if (!is_scene_liboverride || !ID_IS_LINKED(id)) {
+ BKE_id_copy_ex(bmain, id, &id_new, LIB_ID_COPY_ACTIONS);
+ id_us_min(id_new);
+ ID_NEW_SET(id, id_new);
}
}
/* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
* duplicate along the object itself). */
- BKE_collection_duplicate(bmain, NULL, sce_copy->master_collection, true, true);
+ BKE_collection_duplicate(bmain,
+ NULL,
+ sce_copy->master_collection,
+ USER_DUP_OBJECT | U.dupflag,
+ LIB_ID_DUPLICATE_IS_SUBPROCESS);
+
+ if (!is_subprocess) {
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ BKE_libblock_relink_to_newid(&sce_copy->id);
+
+#ifndef NDEBUG
+ /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those
+ * flags. */
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0);
+ }
+ FOREACH_MAIN_ID_END;
+#endif
+
+ /* Cleanup. */
+ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
+ BKE_main_id_clear_newpoins(bmain);
+
+ BKE_main_collection_sync(bmain);
+ }
}
else {
/* Remove sequencer if not full copy */