2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "BLI_blenlib.h"
24 #include "BLI_ghash.h"
25 #include "BLI_iterator.h"
26 #include "BLI_listbase.h"
27 #include "BLI_math_base.h"
28 #include "BLI_threads.h"
29 #include "BLT_translation.h"
31 #include "BKE_collection.h"
32 #include "BKE_icons.h"
33 #include "BKE_idprop.h"
34 #include "BKE_layer.h"
35 #include "BKE_library.h"
37 #include "BKE_object.h"
38 #include "BKE_rigidbody.h"
39 #include "BKE_scene.h"
42 #include "DNA_collection_types.h"
43 #include "DNA_layer_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_query.h"
50 #include "MEM_guardedalloc.h"
52 /******************************** Prototypes ********************************/
54 static bool collection_child_add(Collection *parent, Collection *collection, const int flag, const bool add_us);
55 static bool collection_child_remove(Collection *parent, Collection *collection);
56 static bool collection_object_add(Main *bmain, Collection *collection, Object *ob, int flag, const bool add_us);
57 static bool collection_object_remove(Main *bmain, Collection *collection, Object *ob, const bool free_us);
59 static CollectionChild *collection_find_child(Collection *parent, Collection *collection);
60 static CollectionParent *collection_find_parent(Collection *child, Collection *collection);
62 static bool collection_find_child_recursive(Collection *parent, Collection *collection);
64 /***************************** Add Collection *******************************/
66 /* Add new collection, without view layer syncing. */
67 static Collection *collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
69 /* Determine new collection name. */
73 STRNCPY(name, name_custom);
76 BKE_collection_new_name_get(collection_parent, name);
79 /* Create new collection. */
80 Collection *collection = BKE_libblock_alloc(bmain, ID_GR, name, 0);
82 /* We increase collection user count when linking to Collections. */
83 id_us_min(&collection->id);
85 /* Optionally add to parent collection. */
86 if (collection_parent) {
87 collection_child_add(collection_parent, collection, 0, true);
94 * Add a collection to a collection ListBase and synchronize all render layers
95 * The ListBase is NULL when the collection is to be added to the master collection
97 Collection *BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
99 Collection *collection = collection_add(bmain, collection_parent, name_custom);
100 BKE_main_collection_sync(bmain);
104 /*********************** Free and Delete Collection ****************************/
106 /** Free (or release) any data used by this collection (does not free the collection itself). */
107 void BKE_collection_free(Collection *collection)
109 /* No animdata here. */
110 BKE_previewimg_free(&collection->preview);
112 BLI_freelistN(&collection->gobject);
113 BLI_freelistN(&collection->children);
114 BLI_freelistN(&collection->parents);
116 BKE_collection_object_cache_free(collection);
120 * Remove a collection, optionally removing its child objects or moving
121 * them to parent collections.
123 bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
125 /* Master collection is not real datablock, can't be removed. */
126 if (collection->flag & COLLECTION_IS_MASTER) {
127 BLI_assert(!"Scene master collection can't be deleted");
132 /* Remove child objects. */
133 CollectionObject *cob = collection->gobject.first;
134 while (cob != NULL) {
135 collection_object_remove(bmain, collection, cob->ob, true);
136 cob = collection->gobject.first;
139 /* Delete all child collections recursively. */
140 CollectionChild *child = collection->children.first;
141 while (child != NULL) {
142 BKE_collection_delete(bmain, child->collection, hierarchy);
143 child = collection->children.first;
147 /* Link child collections into parent collection. */
148 for (CollectionChild *child = collection->children.first; child; child = child->next) {
149 for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
150 Collection *parent = cparent->collection;
151 collection_child_add(parent, child->collection, 0, true);
155 CollectionObject *cob = collection->gobject.first;
156 while (cob != NULL) {
157 /* Link child object into parent collections. */
158 for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
159 Collection *parent = cparent->collection;
160 collection_object_add(bmain, parent, cob->ob, 0, true);
163 /* Remove child object. */
164 collection_object_remove(bmain, collection, cob->ob, true);
165 cob = collection->gobject.first;
169 BKE_id_delete(bmain, collection);
171 BKE_main_collection_sync(bmain);
176 /***************************** Collection Copy *******************************/
179 * Only copy internal data of Collection ID from source to already allocated/initialized destination.
180 * You probably never want to use that directly, use BKE_id_copy or BKE_id_copy_ex for typical needs.
182 * WARNING! This function will not handle ID user count!
184 * \param flag: Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
186 void BKE_collection_copy_data(
187 Main *bmain, Collection *collection_dst, const Collection *collection_src, const int flag)
189 /* Do not copy collection's preview (same behavior as for objects). */
190 if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
191 BKE_previewimg_id_copy(&collection_dst->id, &collection_src->id);
194 collection_dst->preview = NULL;
197 collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
198 BLI_listbase_clear(&collection_dst->object_cache);
200 BLI_listbase_clear(&collection_dst->gobject);
201 BLI_listbase_clear(&collection_dst->children);
202 BLI_listbase_clear(&collection_dst->parents);
204 for (CollectionChild *child = collection_src->children.first; child; child = child->next) {
205 collection_child_add(collection_dst, child->collection, flag, false);
207 for (CollectionObject *cob = collection_src->gobject.first; cob; cob = cob->next) {
208 collection_object_add(bmain, collection_dst, cob->ob, flag, false);
213 * Makes a shallow copy of a Collection
215 * Add a new collection in the same level as the old one, copy any nested collections
216 * but link the objects to the new collection (as oppose to copy them).
218 Collection *BKE_collection_copy(Main *bmain, Collection *parent, Collection *collection)
220 /* It's not allowed to copy the master collection. */
221 if (collection->flag & COLLECTION_IS_MASTER) {
222 BLI_assert("!Master collection can't be copied");
226 Collection *collection_new;
227 BKE_id_copy(bmain, &collection->id, (ID **)&collection_new);
228 id_us_min(&collection_new->id); /* Copying add one user by default, need to get rid of that one. */
230 /* Optionally add to parent. */
232 if (collection_child_add(parent, collection_new, 0, true)) {
233 /* Put collection right after existing one. */
234 CollectionChild *child = collection_find_child(parent, collection);
235 CollectionChild *child_new = collection_find_child(parent, collection_new);
237 if (child && child_new) {
238 BLI_remlink(&parent->children, child_new);
239 BLI_insertlinkafter(&parent->children, child, child_new);
244 BKE_main_collection_sync(bmain);
246 return collection_new;
249 Collection *BKE_collection_copy_master(Main *bmain, Collection *collection, const int flag)
251 BLI_assert(collection->flag & COLLECTION_IS_MASTER);
253 Collection *collection_dst = MEM_dupallocN(collection);
254 BKE_collection_copy_data(bmain, collection_dst, collection, flag);
255 return collection_dst;
258 void BKE_collection_copy_full(Main *UNUSED(bmain), Collection *UNUSED(collection))
260 // TODO: implement full scene copy
263 void BKE_collection_make_local(Main *bmain, Collection *collection, const bool lib_local)
265 BKE_id_make_local_generic(bmain, &collection->id, true, lib_local);
268 /********************************* Naming *******************************/
271 * The automatic/fallback name of a new collection.
273 void BKE_collection_new_name_get(Collection *collection_parent, char *rname)
277 if (!collection_parent) {
278 name = BLI_sprintfN("Collection");
280 else if (collection_parent->flag & COLLECTION_IS_MASTER) {
281 name = BLI_sprintfN("Collection %d", BLI_listbase_count(&collection_parent->children) + 1);
284 const int number = BLI_listbase_count(&collection_parent->children) + 1;
285 const int digits = integer_digits_i(number);
287 sizeof(collection_parent->id.name) - 1 /* NULL terminator */ - (1 + digits) /* " %d" */ - 2 /* ID */;
288 name = BLI_sprintfN("%.*s %d", max_len, collection_parent->id.name + 2, number);
291 BLI_strncpy(rname, name, MAX_NAME);
296 * The name to show in the interface.
298 const char *BKE_collection_ui_name_get(struct Collection *collection)
300 if (collection->flag & COLLECTION_IS_MASTER) {
301 return IFACE_("Scene Collection");
304 return collection->id.name + 2;
308 /* **************** Object List Cache *******************/
310 static void collection_object_cache_fill(ListBase *lb, Collection *collection, int parent_restrict)
312 int child_restrict = collection->flag | parent_restrict;
314 for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
315 Base *base = BLI_findptr(lb, cob->ob, offsetof(Base, object));
318 base = MEM_callocN(sizeof(Base), "Object Base");
319 base->object = cob->ob;
320 BLI_addtail(lb, base);
323 int object_restrict = base->object->restrictflag;
325 if (((child_restrict & COLLECTION_RESTRICT_VIEW) == 0) &&
326 ((object_restrict & OB_RESTRICT_VIEW) == 0))
328 base->flag |= BASE_ENABLED_VIEWPORT;
331 if (((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) &&
332 ((object_restrict & OB_RESTRICT_RENDER) == 0))
334 base->flag |= BASE_ENABLED_RENDER;
338 for (CollectionChild *child = collection->children.first; child; child = child->next) {
339 collection_object_cache_fill(lb, child->collection, child_restrict);
343 ListBase BKE_collection_object_cache_get(Collection *collection)
345 if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
346 static ThreadMutex cache_lock = BLI_MUTEX_INITIALIZER;
348 BLI_mutex_lock(&cache_lock);
349 if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
350 collection_object_cache_fill(&collection->object_cache, collection, 0);
351 collection->flag |= COLLECTION_HAS_OBJECT_CACHE;
353 BLI_mutex_unlock(&cache_lock);
356 return collection->object_cache;
359 static void collection_object_cache_free(Collection *collection)
361 /* Clear own cache an for all parents, since those are affected by changes as well. */
362 collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
363 BLI_freelistN(&collection->object_cache);
365 for (CollectionParent *parent = collection->parents.first; parent; parent = parent->next) {
366 collection_object_cache_free(parent->collection);
370 void BKE_collection_object_cache_free(Collection *collection)
372 collection_object_cache_free(collection);
375 Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *collection)
378 return BKE_collection_object_cache_get(collection).first;
381 return FIRSTBASE(view_layer);
385 /*********************** Scene Master Collection ***************/
387 Collection *BKE_collection_master_add()
389 /* Not an actual datablock, but owned by scene. */
390 Collection *master_collection = MEM_callocN(sizeof(Collection), "Master Collection");
391 STRNCPY(master_collection->id.name, "GRMaster Collection");
392 master_collection->flag |= COLLECTION_IS_MASTER;
393 return master_collection;
396 Collection *BKE_collection_master(const Scene *scene)
398 return scene->master_collection;
401 /*********************** Cyclic Checks ************************/
403 static bool collection_object_cyclic_check_internal(Object *object, Collection *collection)
405 if (object->instance_collection) {
406 Collection *dup_collection = object->instance_collection;
407 if ((dup_collection->id.tag & LIB_TAG_DOIT) == 0) {
408 /* Cycle already exists in collections, let's prevent further crappyness */
411 /* flag the object to identify cyclic dependencies in further dupli collections */
412 dup_collection->id.tag &= ~LIB_TAG_DOIT;
414 if (dup_collection == collection) {
418 FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(dup_collection, collection_object)
420 if (collection_object_cyclic_check_internal(collection_object, dup_collection)) {
424 FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
427 /* un-flag the object, it's allowed to have the same collection multiple times in parallel */
428 dup_collection->id.tag |= LIB_TAG_DOIT;
434 bool BKE_collection_object_cyclic_check(Main *bmain, Object *object, Collection *collection)
436 /* first flag all collections */
437 BKE_main_id_tag_listbase(&bmain->collection, LIB_TAG_DOIT, true);
439 return collection_object_cyclic_check_internal(object, collection);
442 /******************* Collection Object Membership *******************/
444 bool BKE_collection_has_object(Collection *collection, Object *ob)
446 if (ELEM(NULL, collection, ob)) {
450 return (BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob)));
453 bool BKE_collection_has_object_recursive(Collection *collection, Object *ob)
455 if (ELEM(NULL, collection, ob)) {
459 const ListBase objects = BKE_collection_object_cache_get(collection);
460 return (BLI_findptr(&objects, ob, offsetof(Base, object)));
463 Collection *BKE_collection_object_find(Main *bmain, Collection *collection, Object *ob)
466 collection = collection->id.next;
468 collection = bmain->collection.first;
471 if (BKE_collection_has_object(collection, ob))
473 collection = collection->id.next;
478 bool BKE_collection_is_empty(Collection *collection)
480 return BLI_listbase_is_empty(&collection->gobject) && BLI_listbase_is_empty(&collection->children);
483 /********************** Collection Objects *********************/
485 static bool collection_object_add(Main *bmain, Collection *collection, Object *ob, int flag, const bool add_us)
487 if (ob->instance_collection) {
488 /* Cyclic dependency check. */
489 if (collection_find_child_recursive(ob->instance_collection, collection)) {
494 CollectionObject *cob = BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
499 cob = MEM_callocN(sizeof(CollectionObject), __func__);
501 BLI_addtail(&collection->gobject, cob);
502 BKE_collection_object_cache_free(collection);
504 if (add_us && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
508 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
509 DEG_id_tag_update_ex(bmain, &collection->id, ID_RECALC_COPY_ON_WRITE);
512 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
513 BKE_rigidbody_main_collection_object_add(bmain, collection, ob);
519 static bool collection_object_remove(Main *bmain, Collection *collection, Object *ob, const bool free_us)
521 CollectionObject *cob = BLI_findptr(&collection->gobject, ob, offsetof(CollectionObject, ob));
526 BLI_freelinkN(&collection->gobject, cob);
527 BKE_collection_object_cache_free(collection);
530 BKE_id_free_us(bmain, ob);
536 DEG_id_tag_update_ex(bmain, &collection->id, ID_RECALC_COPY_ON_WRITE);
542 * Add object to collection
544 bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
546 if (ELEM(NULL, collection, ob)) {
550 if (!collection_object_add(bmain, collection, ob, 0, true)) {
554 if (BKE_collection_is_in_scene(collection)) {
555 BKE_main_collection_sync(bmain);
562 * Add object to all scene collections that reference objects is in
563 * (used to copy objects)
565 void BKE_collection_object_add_from(Main *bmain, Scene *scene, Object *ob_src, Object *ob_dst)
567 FOREACH_SCENE_COLLECTION_BEGIN(scene, collection)
569 if (BKE_collection_has_object(collection, ob_src)) {
570 collection_object_add(bmain, collection, ob_dst, 0, true);
573 FOREACH_SCENE_COLLECTION_END;
575 BKE_main_collection_sync(bmain);
579 * Remove object from collection.
581 bool BKE_collection_object_remove(Main *bmain, Collection *collection, Object *ob, const bool free_us)
583 if (ELEM(NULL, collection, ob)) {
587 if (!collection_object_remove(bmain, collection, ob, free_us)) {
591 if (BKE_collection_is_in_scene(collection)) {
592 BKE_main_collection_sync(bmain);
599 * Remove object from all collections of scene
600 * \param scene_collection_skip: Don't remove base from this collection.
602 static bool scene_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us,
603 Collection *collection_skip)
605 bool removed = false;
607 if (collection_skip == NULL) {
608 BKE_scene_remove_rigidbody_object(bmain, scene, ob);
611 FOREACH_SCENE_COLLECTION_BEGIN(scene, collection)
613 if (collection != collection_skip) {
614 removed |= collection_object_remove(bmain, collection, ob, free_us);
617 FOREACH_SCENE_COLLECTION_END;
619 BKE_main_collection_sync(bmain);
625 * Remove object from all collections of scene
627 bool BKE_scene_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us)
629 return scene_collections_object_remove(bmain, scene, ob, free_us, NULL);
633 * Remove all NULL objects from collections.
634 * This is used for library remapping, where these pointers have been set to NULL.
635 * Otherwise this should never happen.
637 static void collection_object_remove_nulls(Collection *collection)
639 bool changed = false;
641 for (CollectionObject *cob = collection->gobject.first, *cob_next = NULL; cob; cob = cob_next) {
642 cob_next = cob->next;
644 if (cob->ob == NULL) {
645 BLI_freelinkN(&collection->gobject, cob);
651 BKE_collection_object_cache_free(collection);
655 void BKE_collections_object_remove_nulls(Main *bmain)
657 for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) {
658 collection_object_remove_nulls(scene->master_collection);
661 for (Collection *collection = bmain->collection.first; collection; collection = collection->id.next) {
662 collection_object_remove_nulls(collection);
666 static void collection_null_children_remove(Collection *collection)
668 for (CollectionChild *child = collection->children.first, *child_next = NULL; child; child = child_next) {
669 child_next = child->next;
671 if (child->collection == NULL) {
672 BLI_freelinkN(&collection->children, child);
677 static void collection_missing_parents_remove(Collection *collection)
679 for (CollectionParent *parent = collection->parents.first, *parent_next; parent != NULL; parent = parent_next) {
680 parent_next = parent->next;
681 if ((parent->collection == NULL) ||
682 !collection_find_child(parent->collection, collection))
684 BLI_freelinkN(&collection->parents, parent);
690 * Remove all NULL children from parent collections of changed \a collection.
691 * This is used for library remapping, where these pointers have been set to NULL.
692 * Otherwise this should never happen.
694 * \note caller must ensure BKE_main_collection_sync_remap() is called afterwards!
696 * \param collection: may be \a NULL, in which case whole \a bmain database of collections is checked.
698 void BKE_collections_child_remove_nulls(Main *bmain, Collection *collection)
700 if (collection == NULL) {
701 /* We need to do the checks in two steps when more than one collection may be involved,
702 * otherwise we can miss some cases...
703 * Also, master collections are not in bmain, so we also need to loop over scenes.
705 for (collection = bmain->collection.first; collection != NULL; collection = collection->id.next) {
706 collection_null_children_remove(collection);
708 for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
709 collection_null_children_remove(BKE_collection_master(scene));
712 for (collection = bmain->collection.first; collection != NULL; collection = collection->id.next) {
713 collection_missing_parents_remove(collection);
715 for (Scene *scene = bmain->scene.first; scene != NULL; scene = scene->id.next) {
716 collection_missing_parents_remove(BKE_collection_master(scene));
720 for (CollectionParent *parent = collection->parents.first, *parent_next; parent; parent = parent_next) {
721 parent_next = parent->next;
723 collection_null_children_remove(parent->collection);
725 if (!collection_find_child(parent->collection, collection)) {
726 BLI_freelinkN(&collection->parents, parent);
733 * Move object from a collection into another
735 * If source collection is NULL move it from all the existing collections.
737 void BKE_collection_object_move(
738 Main *bmain, Scene *scene, Collection *collection_dst, Collection *collection_src, Object *ob)
740 /* In both cases we first add the object, then remove it from the other collections.
741 * Otherwise we lose the original base and whether it was active and selected. */
742 if (collection_src != NULL) {
743 if (BKE_collection_object_add(bmain, collection_dst, ob)) {
744 BKE_collection_object_remove(bmain, collection_src, ob, false);
748 /* Adding will fail if object is already in collection.
749 * However we still need to remove it from the other collections. */
750 BKE_collection_object_add(bmain, collection_dst, ob);
751 scene_collections_object_remove(bmain, scene, ob, false, collection_dst);
755 /***************** Collection Scene Membership ****************/
757 bool BKE_collection_is_in_scene(Collection *collection)
759 if (collection->flag & COLLECTION_IS_MASTER) {
763 for (CollectionParent *cparent = collection->parents.first; cparent; cparent = cparent->next) {
764 if (BKE_collection_is_in_scene(cparent->collection)) {
772 void BKE_collections_after_lib_link(Main *bmain)
774 /* Need to update layer collections because objects might have changed
775 * in linked files, and because undo push does not include updated base
776 * flags since those are refreshed after the operator completes. */
777 BKE_main_collection_sync(bmain);
780 /********************** Collection Children *******************/
782 bool BKE_collection_find_cycle(Collection *new_ancestor, Collection *collection)
784 if (collection == new_ancestor) {
788 for (CollectionParent *parent = new_ancestor->parents.first; parent; parent = parent->next) {
789 if (BKE_collection_find_cycle(parent->collection, collection)) {
797 static CollectionChild *collection_find_child(Collection *parent, Collection *collection)
799 return BLI_findptr(&parent->children, collection, offsetof(CollectionChild, collection));
802 static bool collection_find_child_recursive(Collection *parent, Collection *collection)
804 for (CollectionChild *child = parent->children.first; child; child = child->next) {
805 if (child->collection == collection) {
809 if (collection_find_child_recursive(child->collection, collection)) {
817 static CollectionParent *collection_find_parent(Collection *child, Collection *collection)
819 return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection));
822 static bool collection_child_add(Collection *parent, Collection *collection, const int flag, const bool add_us)
824 CollectionChild *child = collection_find_child(parent, collection);
828 if (BKE_collection_find_cycle(parent, collection)) {
832 child = MEM_callocN(sizeof(CollectionChild), "CollectionChild");
833 child->collection = collection;
834 BLI_addtail(&parent->children, child);
836 /* Don't add parent links for depsgraph datablocks, these are not kept in sync. */
837 if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
838 CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
839 cparent->collection = parent;
840 BLI_addtail(&collection->parents, cparent);
844 id_us_plus(&collection->id);
847 BKE_collection_object_cache_free(parent);
852 static bool collection_child_remove(Collection *parent, Collection *collection)
854 CollectionChild *child = collection_find_child(parent, collection);
859 CollectionParent *cparent = collection_find_parent(collection, parent);
860 BLI_freelinkN(&collection->parents, cparent);
861 BLI_freelinkN(&parent->children, child);
863 id_us_min(&collection->id);
865 BKE_collection_object_cache_free(parent);
870 bool BKE_collection_child_add(Main *bmain, Collection *parent, Collection *child)
872 if (!collection_child_add(parent, child, 0, true)) {
876 BKE_main_collection_sync(bmain);
880 bool BKE_collection_child_remove(Main *bmain, Collection *parent, Collection *child)
882 if (!collection_child_remove(parent, child)) {
886 BKE_main_collection_sync(bmain);
890 /********************** Collection index *********************/
892 static Collection *collection_from_index_recursive(Collection *collection, const int index, int *index_current)
894 if (index == (*index_current)) {
900 for (CollectionChild *child = collection->children.first; child; child = child->next) {
901 Collection *nested = collection_from_index_recursive(child->collection, index, index_current);
902 if (nested != NULL) {
910 * Return Scene Collection for a given index.
912 * The index is calculated from top to bottom counting the children before the siblings.
914 Collection *BKE_collection_from_index(Scene *scene, const int index)
916 int index_current = 0;
917 Collection *master_collection = BKE_collection_master(scene);
918 return collection_from_index_recursive(master_collection, index, &index_current);
921 static bool collection_objects_select(ViewLayer *view_layer, Collection *collection, bool deselect)
923 bool changed = false;
925 if (collection->flag & COLLECTION_RESTRICT_SELECT) {
929 for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
930 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
934 if (base->flag & BASE_SELECTED) {
935 base->flag &= ~BASE_SELECTED;
940 if ((base->flag & BASE_SELECTABLE) && !(base->flag & BASE_SELECTED)) {
941 base->flag |= BASE_SELECTED;
948 for (CollectionChild *child = collection->children.first; child; child = child->next) {
949 if (collection_objects_select(view_layer, collection, deselect)) {
958 * Select all the objects in this Collection (and its nested collections) for this ViewLayer.
959 * Return true if any object was selected.
961 bool BKE_collection_objects_select(ViewLayer *view_layer, Collection *collection, bool deselect)
963 LayerCollection *layer_collection = BKE_layer_collection_first_from_scene_collection(view_layer, collection);
965 if (layer_collection != NULL) {
966 return BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
969 return collection_objects_select(view_layer, collection, deselect);
973 /***************** Collection move (outliner drag & drop) *********************/
975 bool BKE_collection_move(Main *bmain,
976 Collection *to_parent,
977 Collection *from_parent,
978 Collection *relative,
980 Collection *collection)
982 if (collection->flag & COLLECTION_IS_MASTER) {
985 if (BKE_collection_find_cycle(to_parent, collection)) {
989 /* Move to new parent collection */
991 collection_child_remove(from_parent, collection);
994 collection_child_add(to_parent, collection, 0, true);
996 /* Move to specified location under parent. */
998 CollectionChild *child = collection_find_child(to_parent, collection);
999 CollectionChild *relative_child = collection_find_child(to_parent, relative);
1001 if (relative_child) {
1002 BLI_remlink(&to_parent->children, child);
1004 if (relative_after) {
1005 BLI_insertlinkafter(&to_parent->children, relative_child, child);
1008 BLI_insertlinkbefore(&to_parent->children, relative_child, child);
1011 BKE_collection_object_cache_free(to_parent);
1015 BKE_main_collection_sync(bmain);
1020 /**************************** Iterators ******************************/
1022 /* scene collection iteractor */
1024 typedef struct CollectionsIteratorData {
1028 } CollectionsIteratorData;
1030 static void scene_collection_callback(Collection *collection, BKE_scene_collections_Cb callback, void *data)
1032 callback(collection, data);
1034 for (CollectionChild *child = collection->children.first; child; child = child->next) {
1035 scene_collection_callback(child->collection, callback, data);
1039 static void scene_collections_count(Collection *UNUSED(collection), void *data)
1045 static void scene_collections_build_array(Collection *collection, void *data)
1047 Collection ***array = data;
1048 **array = collection;
1052 static void scene_collections_array(Scene *scene, Collection ***collections_array, int *tot)
1054 Collection *collection;
1057 *collections_array = NULL;
1060 if (scene == NULL) {
1064 collection = BKE_collection_master(scene);
1065 BLI_assert(collection != NULL);
1066 scene_collection_callback(collection, scene_collections_count, tot);
1071 *collections_array = array = MEM_mallocN(sizeof(Collection *) * (*tot), "CollectionArray");
1072 scene_collection_callback(collection, scene_collections_build_array, &array);
1076 * Only use this in non-performance critical situations
1077 * (it iterates over all scene collections twice)
1079 void BKE_scene_collections_iterator_begin(BLI_Iterator *iter, void *data_in)
1081 Scene *scene = data_in;
1082 CollectionsIteratorData *data = MEM_callocN(sizeof(CollectionsIteratorData), __func__);
1084 data->scene = scene;
1088 scene_collections_array(scene, (Collection ***)&data->array, &data->tot);
1089 BLI_assert(data->tot != 0);
1092 iter->current = data->array[data->cur];
1095 void BKE_scene_collections_iterator_next(struct BLI_Iterator *iter)
1097 CollectionsIteratorData *data = iter->data;
1099 if (++data->cur < data->tot) {
1100 iter->current = data->array[data->cur];
1103 iter->valid = false;
1107 void BKE_scene_collections_iterator_end(struct BLI_Iterator *iter)
1109 CollectionsIteratorData *data = iter->data;
1113 MEM_freeN(data->array);
1117 iter->valid = false;
1121 /* scene objects iterator */
1123 typedef struct SceneObjectsIteratorData {
1125 CollectionObject *cob_next;
1126 BLI_Iterator scene_collection_iter;
1127 } SceneObjectsIteratorData;
1129 void BKE_scene_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
1131 Scene *scene = data_in;
1132 SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __func__);
1135 /* lookup list ot make sure each object is object called once */
1136 data->visited = BLI_gset_ptr_new(__func__);
1138 /* we wrap the scenecollection iterator here to go over the scene collections */
1139 BKE_scene_collections_iterator_begin(&data->scene_collection_iter, scene);
1141 Collection *collection = data->scene_collection_iter.current;
1142 data->cob_next = collection->gobject.first;
1144 BKE_scene_objects_iterator_next(iter);
1148 * Ensures we only get each object once, even when included in several collections.
1150 static CollectionObject *object_base_unique(GSet *gs, CollectionObject *cob)
1152 for (; cob != NULL; cob = cob->next) {
1153 Object *ob = cob->ob;
1155 if (!BLI_gset_ensure_p_ex(gs, ob, &ob_key_p)) {
1163 void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
1165 SceneObjectsIteratorData *data = iter->data;
1166 CollectionObject *cob = data->cob_next ? object_base_unique(data->visited, data->cob_next) : NULL;
1169 data->cob_next = cob->next;
1170 iter->current = cob->ob;
1173 /* if this is the last object of this ListBase look at the next Collection */
1174 Collection *collection;
1175 BKE_scene_collections_iterator_next(&data->scene_collection_iter);
1177 collection = data->scene_collection_iter.current;
1178 /* get the first unique object of this collection */
1179 CollectionObject *new_cob = object_base_unique(data->visited, collection->gobject.first);
1181 data->cob_next = new_cob->next;
1182 iter->current = new_cob->ob;
1185 BKE_scene_collections_iterator_next(&data->scene_collection_iter);
1186 } while (data->scene_collection_iter.valid);
1188 if (!data->scene_collection_iter.valid) {
1189 iter->valid = false;
1194 void BKE_scene_objects_iterator_end(BLI_Iterator *iter)
1196 SceneObjectsIteratorData *data = iter->data;
1198 BKE_scene_collections_iterator_end(&data->scene_collection_iter);
1199 BLI_gset_free(data->visited, NULL);