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:
Diffstat (limited to 'source/blender/blenkernel/intern/collection.c')
-rw-r--r--source/blender/blenkernel/intern/collection.c101
1 files changed, 47 insertions, 54 deletions
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 6f63da18a22..080d61f1500 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -28,6 +28,7 @@
#include "BLI_threads.h"
#include "BLT_translation.h"
+#include "BKE_anim_data.h"
#include "BKE_collection.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
@@ -326,16 +327,16 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
static Collection *collection_duplicate_recursive(Main *bmain,
Collection *parent,
Collection *collection_old,
- const bool do_hierarchy,
- const bool do_objects,
- const bool do_obdata)
+ const eDupli_ID_Flags duplicate_flags,
+ const eLibIDDuplicateFlags duplicate_options)
{
Collection *collection_new;
bool do_full_process = false;
- const int object_dupflag = (do_obdata) ? U.dupflag : 0;
const bool is_collection_master = (collection_old->flag & COLLECTION_IS_MASTER) != 0;
const bool is_collection_liboverride = ID_IS_OVERRIDE_LIBRARY(collection_old);
+ const bool do_objects = (duplicate_flags & USER_DUP_OBJECT) != 0;
+
if (is_collection_master) {
/* We never duplicate master collections here, but we can still deep-copy their objects and
* collections. */
@@ -343,15 +344,9 @@ static Collection *collection_duplicate_recursive(Main *bmain,
collection_new = collection_old;
do_full_process = true;
}
- else if (!do_hierarchy || 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);
-
- if (do_hierarchy) {
- ID_NEW_SET(collection_old, collection_new);
- }
+ else if (collection_old->id.newid == NULL) {
+ collection_new = (Collection *)BKE_id_copy_for_duplicate(
+ bmain, (ID *)collection_old, is_collection_liboverride, duplicate_flags);
do_full_process = true;
}
else {
@@ -376,7 +371,7 @@ static Collection *collection_duplicate_recursive(Main *bmain,
/* If we are not doing any kind of deep-copy, we can return immediately.
* False do_full_process means collection_old had already been duplicated,
* no need to redo some deep-copy on it. */
- if (!do_hierarchy || !do_full_process) {
+ if (!do_full_process) {
return collection_new;
}
@@ -394,8 +389,8 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
if (ob_new == NULL) {
- ob_new = BKE_object_duplicate(bmain, ob_old, object_dupflag);
- ID_NEW_SET(ob_old, ob_new);
+ ob_new = BKE_object_duplicate(
+ bmain, ob_old, duplicate_flags, duplicate_options | LIB_ID_DUPLICATE_IS_SUBPROCESS);
}
collection_object_add(bmain, collection_new, ob_new, 0, true);
@@ -413,7 +408,7 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
collection_duplicate_recursive(
- bmain, collection_new, child_collection_old, do_hierarchy, do_objects, do_obdata);
+ bmain, collection_new, child_collection_old, duplicate_flags, duplicate_options);
collection_child_remove(collection_new, child_collection_old);
}
@@ -421,56 +416,54 @@ static Collection *collection_duplicate_recursive(Main *bmain,
}
/**
- * Makes a standard (aka shallow) ID copy of a Collection.
- *
- * Add a new collection in the same level as the old one, link any nested collections
- * and finally link the objects to the new collection (as opposed to copying them).
- */
-Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *collection)
-{
- return BKE_collection_duplicate(bmain, parent, collection, false, false, false);
-}
-
-/**
- * Make either a shallow copy, or deeper duplicate of given collection.
+ * Make a deep copy (aka duplicate) of the given collection and all of its children, recursively.
*
- * If \a do_hierarchy and \a do_deep_copy are false, this is a regular (shallow) ID copy.
- *
- * \warning If any 'deep copy' behavior is enabled,
- * this functions will clear all \a bmain id.idnew pointers.
- *
- * \param do_hierarchy: If true, it will recursively make shallow copies of children collections.
- * \param do_objects: If true, it will also make duplicates of objects.
- * This one does nothing if \a do_hierarchy is not set.
- * \param do_obdata: If true, it will also make deep duplicates of objects,
- * using behavior defined in user settings (#U.dupflag).
- * This one does nothing if \a do_hierarchy and \a do_objects are not set.
+ * \warning This functions will clear all \a bmain #ID.idnew pointers, unless \a
+ * #LIB_ID_DUPLICATE_IS_SUBPROCESS duplicate option is passed on, in which case caller is
+ * responsible to reconstruct collection dependencies information's
+ * (i.e. call #BKE_main_collection_sync).
*/
Collection *BKE_collection_duplicate(Main *bmain,
Collection *parent,
Collection *collection,
- const bool do_hierarchy,
- const bool do_objects,
- const bool do_obdata)
+ eDupli_ID_Flags duplicate_flags,
+ eLibIDDuplicateFlags duplicate_options)
{
- if (do_hierarchy) {
+ const bool is_subprocess = (duplicate_options & LIB_ID_DUPLICATE_IS_SUBPROCESS) != 0;
+
+ if (!is_subprocess) {
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
}
Collection *collection_new = collection_duplicate_recursive(
- bmain, parent, collection, do_hierarchy, do_objects, do_obdata);
-
- /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
- BKE_libblock_relink_to_newid(&collection_new->id);
+ bmain, parent, collection, duplicate_flags, duplicate_options);
+
+ if (!is_subprocess) {
+ /* `collection_duplicate_recursive` will also tag our 'root' collection, which is not required
+ * unless its duplication is a sub-process of another one. */
+ collection_new->id.tag &= ~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);
+
+#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) {
+ if (id_iter->tag & LIB_TAG_NEW) {
+ BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0);
+ }
+ }
+ FOREACH_MAIN_ID_END;
+#endif
- if (do_hierarchy) {
/* Cleanup. */
BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
BKE_main_id_clear_newpoins(bmain);
- }
- BKE_main_collection_sync(bmain);
+ BKE_main_collection_sync(bmain);
+ }
return collection_new;
}
@@ -927,7 +920,7 @@ bool BKE_collection_object_remove(Main *bmain,
/**
* Remove object from all collections of scene
- * \param scene_collection_skip: Don't remove base from this collection.
+ * \param collection_skip: Don't remove base from this collection.
*/
static bool scene_collections_object_remove(
Main *bmain, Scene *scene, Object *ob, const bool free_us, Collection *collection_skip)
@@ -1126,7 +1119,7 @@ static bool collection_find_instance_recursive(Collection *collection,
{
LISTBASE_FOREACH (CollectionObject *, collection_object, &collection->gobject) {
if (collection_object->ob != NULL &&
- /* Object from a given collection should never instanciate that collection either. */
+ /* Object from a given collection should never instantiate that collection either. */
ELEM(collection_object->ob->instance_collection, instance_collection, collection)) {
return true;
}
@@ -1153,7 +1146,7 @@ bool BKE_collection_find_cycle(Collection *new_ancestor, Collection *collection)
}
}
- /* Find possible objects in collection or its children, that would instanciate the given ancestor
+ /* Find possible objects in collection or its children, that would instantiate the given ancestor
* collection (that would also make a fully invalid cycle of dependencies) .*/
return collection_find_instance_recursive(collection, new_ancestor);
}