Fix collection syncing when creating new collections from the outliner
[blender.git] / source / blender / blenkernel / intern / collection.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Dalai Felinto
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/blenkernel/intern/collection.c
24  *  \ingroup bke
25  */
26
27 #include <string.h>
28
29 #include "BLI_blenlib.h"
30 #include "BLI_ghash.h"
31 #include "BLI_iterator.h"
32 #include "BLI_listbase.h"
33 #include "BLI_math_base.h"
34 #include "BLT_translation.h"
35 #include "BLI_string_utils.h"
36
37 #include "BKE_collection.h"
38 #include "BKE_group.h"
39 #include "BKE_idprop.h"
40 #include "BKE_layer.h"
41 #include "BKE_library.h"
42 #include "BKE_main.h"
43 #include "BKE_scene.h"
44
45 #include "DNA_group_types.h"
46 #include "DNA_ID.h"
47 #include "DNA_layer_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_scene_types.h"
50
51 #include "MEM_guardedalloc.h"
52
53 /* Prototypes. */
54 static SceneCollection *find_collection_parent(const struct SceneCollection *sc_child, struct SceneCollection *sc_parent);
55 static bool is_collection_in_tree(const struct SceneCollection *sc_reference, struct SceneCollection *sc_parent);
56
57 static SceneCollection *collection_master_from_id(const ID *owner_id)
58 {
59         switch (GS(owner_id->name)) {
60                 case ID_SCE:
61                         return ((Scene *)owner_id)->collection;
62                 case ID_GR:
63                         return ((Group *)owner_id)->collection;
64                 default:
65                         BLI_assert(!"ID doesn't support collections");
66                         return NULL;
67         }
68 }
69
70 /**
71  * Add a new collection, but don't handle syncing with layer collections
72  */
73 static SceneCollection *collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom)
74 {
75         SceneCollection *sc_master = collection_master_from_id(owner_id);
76         SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
77         sc->type = type;
78         const char *name = name_custom;
79
80         if (!sc_parent) {
81                 sc_parent = sc_master;
82         }
83
84         if (!name) {
85                 if (sc_parent == sc_master) {
86                         name = BLI_sprintfN("Collection %d", BLI_listbase_count(&sc_master->scene_collections) + 1);
87                 }
88                 else {
89                         const int number = BLI_listbase_count(&sc_parent->scene_collections) + 1;
90                         const int digits = integer_digits_i(number);
91                         const int max_len = sizeof(sc_parent->name)
92                                             - 1 /* NULL terminator */
93                                             - (1 + digits) /* " %d" */;
94                         name = BLI_sprintfN("%.*s %d", max_len, sc_parent->name, number);
95                 }
96         }
97
98         BLI_addtail(&sc_parent->scene_collections, sc);
99         BKE_collection_rename((Scene *)owner_id, sc, name);
100
101         if (name != name_custom) {
102                 MEM_freeN((char *)name);
103         }
104
105         return sc;
106 }
107
108 /**
109  * Add a collection to a collection ListBase and syncronize all render layers
110  * The ListBase is NULL when the collection is to be added to the master collection
111  */
112 SceneCollection *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name_custom)
113 {
114         if (sc_parent == NULL) {
115                 sc_parent = BKE_collection_master(owner_id);
116         }
117
118         SceneCollection *scene_collection = collection_add(owner_id, sc_parent, type, name_custom);
119         BKE_layer_sync_new_scene_collection(owner_id, sc_parent, scene_collection);
120         return scene_collection;
121 }
122
123 /**
124  * Free the collection items recursively
125  */
126 static void collection_free(SceneCollection *sc, const bool do_id_user)
127 {
128         if (do_id_user) {
129                 for (LinkData *link = sc->objects.first; link; link = link->next) {
130                         id_us_min(link->data);
131                 }
132         }
133
134         BLI_freelistN(&sc->objects);
135
136         for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
137                 collection_free(nsc, do_id_user);
138         }
139         BLI_freelistN(&sc->scene_collections);
140 }
141
142 /**
143  * Unlink the collection recursively
144  * \return true if unlinked.
145  */
146 static bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
147 {
148         for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next) {
149                 if (sc == sc_gone) {
150                         BLI_remlink(&sc_parent->scene_collections, sc_gone);
151                         return true;
152                 }
153
154                 if (collection_remlink(sc, sc_gone)) {
155                         return true;
156                 }
157         }
158         return false;
159 }
160
161 /**
162  * Recursively remove any instance of this SceneCollection
163  */
164 static void layer_collection_remove(ViewLayer *view_layer, ListBase *lb, const SceneCollection *sc)
165 {
166         LayerCollection *lc = lb->first;
167         while (lc) {
168                 if (lc->scene_collection == sc) {
169                         BKE_layer_collection_free(view_layer, lc);
170                         BLI_remlink(lb, lc);
171
172                         LayerCollection *lc_next = lc->next;
173                         MEM_freeN(lc);
174                         lc = lc_next;
175
176                         /* only the "top-level" layer collections may have the
177                          * same SceneCollection in a sibling tree.
178                          */
179                         if (lb != &view_layer->layer_collections) {
180                                 return;
181                         }
182                 }
183
184                 else {
185                         layer_collection_remove(view_layer, &lc->layer_collections, sc);
186                         lc = lc->next;
187                 }
188         }
189 }
190
191 /**
192  * Remove a collection from the scene, and syncronize all render layers
193  *
194  * If an object is in any other collection, link the object to the master collection.
195  */
196 bool BKE_collection_remove(ID *owner_id, SceneCollection *sc)
197 {
198         SceneCollection *sc_master = collection_master_from_id(owner_id);
199
200         /* The master collection cannot be removed. */
201         if (sc == sc_master) {
202                 return false;
203         }
204
205         /* We need to do bottom up removal, otherwise we get a crash when we remove a collection that
206          * has one of its nested collections linked to a view layer. */
207         SceneCollection *scene_collection_nested = sc->scene_collections.first;
208         while (scene_collection_nested != NULL) {
209                 SceneCollection *scene_collection_next = scene_collection_nested->next;
210                 BKE_collection_remove(owner_id, scene_collection_nested);
211                 scene_collection_nested = scene_collection_next;
212         }
213
214         /* Unlink from the respective collection tree. */
215         if (!collection_remlink(sc_master, sc)) {
216                 BLI_assert(false);
217         }
218
219         /* If an object is no longer in any collection, we add it to the master collection. */
220         ListBase collection_objects;
221         BLI_duplicatelist(&collection_objects, &sc->objects);
222
223         FOREACH_SCENE_COLLECTION(owner_id, scene_collection_iter)
224         {
225                 if (scene_collection_iter == sc) {
226                         continue;
227                 }
228
229                 LinkData *link_next, *link = collection_objects.first;
230                 while (link) {
231                         link_next = link->next;
232
233                         if (BLI_findptr(&scene_collection_iter->objects, link->data, offsetof(LinkData, data))) {
234                                 BLI_remlink(&collection_objects, link);
235                                 MEM_freeN(link);
236                         }
237
238                         link = link_next;
239                 }
240         }
241         FOREACH_SCENE_COLLECTION_END
242
243         for (LinkData *link = collection_objects.first; link; link = link->next) {
244                 BKE_collection_object_add(owner_id, sc_master, link->data);
245         }
246
247         BLI_freelistN(&collection_objects);
248
249         /* Clear the collection items. */
250         collection_free(sc, true);
251
252         /* check all layers that use this collection and clear them */
253         for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
254                 layer_collection_remove(view_layer, &view_layer->layer_collections, sc);
255                 view_layer->active_collection = 0;
256         }
257
258         MEM_freeN(sc);
259         return true;
260 }
261
262 /**
263  * Copy SceneCollection tree but keep pointing to the same objects
264  *
265  * \param flag  Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
266  */
267 void BKE_collection_copy_data(SceneCollection *sc_dst, SceneCollection *sc_src, const int flag)
268 {
269         BLI_duplicatelist(&sc_dst->objects, &sc_src->objects);
270         if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
271                 for (LinkData *link = sc_dst->objects.first; link; link = link->next) {
272                         id_us_plus(link->data);
273                 }
274         }
275
276         BLI_duplicatelist(&sc_dst->scene_collections, &sc_src->scene_collections);
277         for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
278              nsc_src;
279              nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
280         {
281                 BKE_collection_copy_data(nsc_dst, nsc_src, flag);
282         }
283 }
284
285 /**
286  * Makes a shallow copy of a SceneCollection
287  *
288  * Add a new collection in the same level as the old one, copy any nested collections
289  * but link the objects to the new collection (as oppose to copy them).
290  */
291 SceneCollection *BKE_collection_duplicate(ID *owner_id, SceneCollection *scene_collection)
292 {
293         SceneCollection *scene_collection_master = BKE_collection_master(owner_id);
294         SceneCollection *scene_collection_parent = find_collection_parent(scene_collection, scene_collection_master);
295
296         /* It's not allowed to copy the master collection. */
297         if (scene_collection_master == scene_collection) {
298                 return NULL;
299         }
300
301         SceneCollection *scene_collection_new = collection_add(
302                                                     owner_id,
303                                                     scene_collection_parent,
304                                                     scene_collection->type,
305                                                     scene_collection->name);
306
307         if (scene_collection_new != scene_collection->next) {
308                 BLI_remlink(&scene_collection_parent->scene_collections, scene_collection_new);
309                 BLI_insertlinkafter(&scene_collection_parent->scene_collections, scene_collection, scene_collection_new);
310         }
311
312         BKE_collection_copy_data(scene_collection_new, scene_collection, 0);
313         BKE_layer_sync_new_scene_collection(owner_id, scene_collection_parent, scene_collection_new);
314
315         /* Make sure every linked instance of the new collection has the same values (flags, overrides, ...) as the
316          * corresponding original collection. */
317         BKE_layer_collection_sync_flags(owner_id, scene_collection_new, scene_collection);
318
319         return scene_collection_new;
320 }
321
322 static SceneCollection *master_collection_from_id(const ID *owner_id)
323 {
324         switch (GS(owner_id->name)) {
325                 case ID_SCE:
326                         return ((const Scene *)owner_id)->collection;
327                 case ID_GR:
328                         return ((const Group *)owner_id)->collection;
329                 default:
330                         BLI_assert(!"ID doesn't support scene collection");
331                         return NULL;
332         }
333 }
334
335 /**
336  * Returns the master collection of the scene or group
337  */
338 SceneCollection *BKE_collection_master(const ID *owner_id)
339 {
340         return master_collection_from_id(owner_id);
341 }
342
343 static void collection_rename(const ID *owner_id, SceneCollection *sc, const char *name)
344 {
345         SceneCollection *sc_parent = find_collection_parent(sc, collection_master_from_id(owner_id));
346         BLI_strncpy(sc->name, name, sizeof(sc->name));
347         BLI_uniquename(&sc_parent->scene_collections, sc, DATA_("Collection"), '.', offsetof(SceneCollection, name), sizeof(sc->name));
348 }
349
350 void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *name)
351 {
352         collection_rename(&scene->id, sc, name);
353 }
354
355 /**
356  * Make sure the collection name is still unique within its siblings.
357  */
358 static void collection_name_check(const ID *owner_id, SceneCollection *sc)
359 {
360         /* It's a bit of a hack, we simply try to make sure the collection name is valid. */
361         collection_rename(owner_id, sc, sc->name);
362 }
363
364 /**
365  * Free (or release) any data used by the master collection (does not free the master collection itself).
366  * Used only to clear the entire scene or group data since it's not doing re-syncing of the LayerCollection tree
367  */
368 void BKE_collection_master_free(ID *owner_id, const bool do_id_user)
369 {
370         collection_free(BKE_collection_master(owner_id), do_id_user);
371 }
372
373 static void collection_object_add(const ID *owner_id, SceneCollection *sc, Object *ob)
374 {
375         BLI_addtail(&sc->objects, BLI_genericNodeN(ob));
376
377         if (GS(owner_id->name) == ID_SCE) {
378                 id_us_plus((ID *)ob);
379         }
380         else {
381                 BLI_assert(GS(owner_id->name) == ID_GR);
382                 if ((ob->flag & OB_FROMGROUP) == 0) {
383                         ob->flag |= OB_FROMGROUP;
384                 }
385         }
386
387         BKE_layer_sync_object_link(owner_id, sc, ob);
388 }
389
390 /**
391  * Add object to collection
392  */
393 bool BKE_collection_object_add(const ID *owner_id, SceneCollection *sc, Object *ob)
394 {
395         if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
396                 /* don't add the same object twice */
397                 return false;
398         }
399
400         collection_object_add(owner_id, sc, ob);
401         return true;
402 }
403
404 /**
405  * Add object to all collections that reference objects is in
406  * (used to copy objects)
407  */
408 void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst)
409 {
410         FOREACH_SCENE_COLLECTION(scene, sc)
411         {
412                 if (BLI_findptr(&sc->objects, ob_src, offsetof(LinkData, data))) {
413                         collection_object_add(&scene->id, sc, ob_dst);
414                 }
415         }
416         FOREACH_SCENE_COLLECTION_END
417
418         for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
419                 Base *base_src = BKE_view_layer_base_find(view_layer, ob_src);
420                 if (base_src != NULL) {
421                         if (base_src->collection_properties == NULL) {
422                                 continue;
423                         }
424                         Base *base_dst = BKE_view_layer_base_find(view_layer, ob_dst);
425                         IDP_MergeGroup(base_dst->collection_properties, base_src->collection_properties, true);
426                 }
427         }
428 }
429
430 /**
431  * Remove object from collection.
432  * \param bmain: Can be NULL if free_us is false.
433  */
434 bool BKE_collection_object_remove(Main *bmain, ID *owner_id, SceneCollection *sc, Object *ob, const bool free_us)
435 {
436         LinkData *link = BLI_findptr(&sc->objects, ob, offsetof(LinkData, data));
437
438         if (link == NULL) {
439                 return false;
440         }
441
442         BLI_remlink(&sc->objects, link);
443         MEM_freeN(link);
444
445         BKE_layer_sync_object_unlink(owner_id, sc, ob);
446
447         if (GS(owner_id->name) == ID_SCE) {
448                 if (free_us) {
449                         BKE_libblock_free_us(bmain, ob);
450                 }
451                 else {
452                         id_us_min(&ob->id);
453                 }
454         }
455         else {
456                 BLI_assert(GS(owner_id->name) == ID_GR);
457         }
458
459         return true;
460 }
461
462 /**
463  * Move object from a collection into another
464  */
465 void BKE_collection_object_move(ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, Object *ob)
466 {
467         if (BKE_collection_object_add(owner_id, sc_dst, ob)) {
468                 BKE_collection_object_remove(NULL, owner_id, sc_src, ob, false);
469         }
470 }
471
472 /**
473  * Remove object from all collections of scene
474  */
475 bool BKE_collections_object_remove(Main *bmain, ID *owner_id, Object *ob, const bool free_us)
476 {
477         bool removed = false;
478         if (GS(owner_id->name) == ID_SCE) {
479                 BKE_scene_remove_rigidbody_object((Scene *)owner_id, ob);
480         }
481         else {
482                 BLI_assert(GS(owner_id->name) == ID_GR);
483         }
484
485         FOREACH_SCENE_COLLECTION(owner_id, sc)
486         {
487                 removed |= BKE_collection_object_remove(bmain, owner_id, sc, ob, free_us);
488         }
489         FOREACH_SCENE_COLLECTION_END
490         return removed;
491 }
492
493 static void layer_collection_sync(LayerCollection *lc_dst, LayerCollection *lc_src)
494 {
495         lc_dst->flag = lc_src->flag;
496
497         /* Pending: sync overrides. */
498         IDP_MergeGroup(lc_dst->properties, lc_src->properties, true);
499
500         /* Continue recursively. */
501         LayerCollection *lc_dst_nested, *lc_src_nested;
502         lc_src_nested = lc_src->layer_collections.first;
503         for (lc_dst_nested = lc_dst->layer_collections.first;
504              lc_dst_nested && lc_src_nested;
505              lc_dst_nested = lc_dst_nested->next, lc_src_nested = lc_src_nested->next)
506         {
507                 layer_collection_sync(lc_dst_nested, lc_src_nested);
508         }
509 }
510
511 /**
512  * Leave only the master collection in, remove everything else.
513  * @param group
514  */
515 static void collection_group_cleanup(Group *group)
516 {
517         /* Unlink all the LayerCollections. */
518         while (group->view_layer->layer_collections.last != NULL) {
519                 BKE_collection_unlink(group->view_layer, group->view_layer->layer_collections.last);
520         }
521
522         /* Remove all the SceneCollections but the master. */
523         collection_free(group->collection, false);
524 }
525
526 /**
527  * Create a group from a collection
528  *
529  * Any ViewLayer that may have this the related SceneCollection linked is converted
530  * to a Group Collection.
531  */
532 Group *BKE_collection_group_create(Main *bmain, Scene *scene, LayerCollection *lc_src)
533 {
534         SceneCollection *sc_dst, *sc_src = lc_src->scene_collection;
535         LayerCollection *lc_dst;
536
537         /* The master collection can't be converted. */
538         if (sc_src == BKE_collection_master(&scene->id)) {
539                 return NULL;
540         }
541
542         /* If a sub-collection of sc_dst is directly linked into a ViewLayer we can't convert. */
543         for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
544                 for (LayerCollection *lc_child = view_layer->layer_collections.first; lc_child; lc_child = lc_child->next) {
545                         if (is_collection_in_tree(lc_child->scene_collection, sc_src)) {
546                                 return NULL;
547                         }
548                 }
549         }
550
551         /* Create new group with the same data as the original collection. */
552         Group *group = BKE_group_add(bmain, sc_src->name);
553         collection_group_cleanup(group);
554
555         sc_dst = BKE_collection_add(&group->id, NULL, COLLECTION_TYPE_GROUP_INTERNAL, sc_src->name);
556         BKE_collection_copy_data(sc_dst, sc_src, 0);
557         FOREACH_SCENE_COLLECTION(&group->id, sc_group)
558         {
559                 sc_group->type = COLLECTION_TYPE_GROUP_INTERNAL;
560         }
561         FOREACH_SCENE_COLLECTION_END
562
563         lc_dst = BKE_collection_link(group->view_layer, sc_dst);
564         layer_collection_sync(lc_dst, lc_src);
565
566         return group;
567 }
568
569 /* ---------------------------------------------------------------------- */
570 /* Outliner drag and drop */
571
572 /**
573  * Find and return the SceneCollection that has \a sc_child as one of its directly
574  * nested SceneCollection.
575  *
576  * \param sc_parent Initial SceneCollection to look into recursively, usually the master collection
577  */
578 static SceneCollection *find_collection_parent(const SceneCollection *sc_child, SceneCollection *sc_parent)
579 {
580         for (SceneCollection *sc_nested = sc_parent->scene_collections.first; sc_nested; sc_nested = sc_nested->next) {
581                 if (sc_nested == sc_child) {
582                         return sc_parent;
583                 }
584
585                 SceneCollection *found = find_collection_parent(sc_child, sc_nested);
586                 if (found) {
587                         return found;
588                 }
589         }
590
591         return NULL;
592 }
593
594 /**
595  * Check if \a sc_reference is nested to \a sc_parent SceneCollection
596  */
597 static bool is_collection_in_tree(const SceneCollection *sc_reference, SceneCollection *sc_parent)
598 {
599         return find_collection_parent(sc_reference, sc_parent) != NULL;
600 }
601
602 bool BKE_collection_move_above(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src)
603 {
604         /* Find the SceneCollection the sc_src belongs to */
605         SceneCollection *sc_master = master_collection_from_id(owner_id);
606
607         /* Master Layer can't be moved around*/
608         if (ELEM(sc_master, sc_src, sc_dst)) {
609                 return false;
610         }
611
612         /* collection is already where we wanted it to be */
613         if (sc_dst->prev == sc_src) {
614                 return false;
615         }
616
617         /* We can't move a collection fs the destiny collection
618          * is nested to the source collection */
619         if (is_collection_in_tree(sc_dst, sc_src)) {
620                 return false;
621         }
622
623         SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
624         SceneCollection *sc_dst_parent = find_collection_parent(sc_dst, sc_master);
625         BLI_assert(sc_src_parent);
626         BLI_assert(sc_dst_parent);
627
628         /* Remove sc_src from its parent */
629         BLI_remlink(&sc_src_parent->scene_collections, sc_src);
630
631         /* Re-insert it where it belongs */
632         BLI_insertlinkbefore(&sc_dst_parent->scene_collections, sc_dst, sc_src);
633
634         /* Update the tree */
635         BKE_layer_collection_resync(owner_id, sc_src_parent);
636         BKE_layer_collection_resync(owner_id, sc_dst_parent);
637
638         /* Keep names unique. */
639         collection_name_check(owner_id, sc_src);
640
641         return true;
642 }
643
644 bool BKE_collection_move_below(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src)
645 {
646         /* Find the SceneCollection the sc_src belongs to */
647         SceneCollection *sc_master = master_collection_from_id(owner_id);
648
649         /* Master Layer can't be moved around*/
650         if (ELEM(sc_master, sc_src, sc_dst)) {
651                 return false;
652         }
653
654         /* Collection is already where we wanted it to be */
655         if (sc_dst->next == sc_src) {
656                 return false;
657         }
658
659         /* We can't move a collection if the destiny collection
660          * is nested to the source collection */
661         if (is_collection_in_tree(sc_dst, sc_src)) {
662                 return false;
663         }
664
665         SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
666         SceneCollection *sc_dst_parent = find_collection_parent(sc_dst, sc_master);
667         BLI_assert(sc_src_parent);
668         BLI_assert(sc_dst_parent);
669
670         /* Remove sc_src from its parent */
671         BLI_remlink(&sc_src_parent->scene_collections, sc_src);
672
673         /* Re-insert it where it belongs */
674         BLI_insertlinkafter(&sc_dst_parent->scene_collections, sc_dst, sc_src);
675
676         /* Update the tree */
677         BKE_layer_collection_resync(owner_id, sc_src_parent);
678         BKE_layer_collection_resync(owner_id, sc_dst_parent);
679
680         /* Keep names unique. */
681         collection_name_check(owner_id, sc_src);
682
683         return true;
684 }
685
686 bool BKE_collection_move_into(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src)
687 {
688         /* Find the SceneCollection the sc_src belongs to */
689         SceneCollection *sc_master = master_collection_from_id(owner_id);
690         if (sc_src == sc_master) {
691                 return false;
692         }
693
694         /* We can't move a collection if the destiny collection
695          * is nested to the source collection */
696         if (is_collection_in_tree(sc_dst, sc_src)) {
697                 return false;
698         }
699
700         SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
701         BLI_assert(sc_src_parent);
702
703         /* collection is already where we wanted it to be */
704         if (sc_dst->scene_collections.last == sc_src) {
705                 return false;
706         }
707
708         /* Remove sc_src from it */
709         BLI_remlink(&sc_src_parent->scene_collections, sc_src);
710
711         /* Insert sc_src into sc_dst */
712         BLI_addtail(&sc_dst->scene_collections, sc_src);
713
714         /* Update the tree */
715         BKE_layer_collection_resync(owner_id, sc_src_parent);
716         BKE_layer_collection_resync(owner_id, sc_dst);
717
718         /* Keep names unique. */
719         collection_name_check(owner_id, sc_src);
720
721         return true;
722 }
723
724 /* ---------------------------------------------------------------------- */
725 /* Iteractors */
726 /* scene collection iteractor */
727
728 typedef struct SceneCollectionsIteratorData {
729         ID *owner_id;
730         void **array;
731         int tot, cur;
732 } SceneCollectionsIteratorData;
733
734 static void scene_collection_callback(SceneCollection *sc, BKE_scene_collections_Cb callback, void *data)
735 {
736         callback(sc, data);
737
738         for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
739                 scene_collection_callback(nsc, callback, data);
740         }
741 }
742
743 static void scene_collections_count(SceneCollection *UNUSED(sc), void *data)
744 {
745         int *tot = data;
746         (*tot)++;
747 }
748
749 static void scene_collections_build_array(SceneCollection *sc, void *data)
750 {
751         SceneCollection ***array = data;
752         **array = sc;
753         (*array)++;
754 }
755
756 static void scene_collections_array(ID *owner_id, SceneCollection ***collections_array, int *tot)
757 {
758         SceneCollection *sc;
759         SceneCollection **array;
760
761         *collections_array = NULL;
762         *tot = 0;
763
764         if (owner_id == NULL) {
765                 return;
766         }
767
768         sc = master_collection_from_id(owner_id);
769         BLI_assert(sc != NULL);
770         scene_collection_callback(sc, scene_collections_count, tot);
771
772         if (*tot == 0)
773                 return;
774
775         *collections_array = array = MEM_mallocN(sizeof(SceneCollection *) * (*tot), "SceneCollectionArray");
776         scene_collection_callback(sc, scene_collections_build_array, &array);
777 }
778
779 /**
780  * Only use this in non-performance critical situations
781  * (it iterates over all scene collections twice)
782  */
783 void BKE_scene_collections_iterator_begin(BLI_Iterator *iter, void *data_in)
784 {
785         ID *owner_id = data_in;
786         SceneCollectionsIteratorData *data = MEM_callocN(sizeof(SceneCollectionsIteratorData), __func__);
787
788         data->owner_id = owner_id;
789         iter->data = data;
790         iter->valid = true;
791
792         scene_collections_array(owner_id, (SceneCollection ***)&data->array, &data->tot);
793         BLI_assert(data->tot != 0);
794
795         data->cur = 0;
796         iter->current = data->array[data->cur];
797 }
798
799 void BKE_scene_collections_iterator_next(struct BLI_Iterator *iter)
800 {
801         SceneCollectionsIteratorData *data = iter->data;
802
803         if (++data->cur < data->tot) {
804                 iter->current = data->array[data->cur];
805         }
806         else {
807                 iter->valid = false;
808         }
809 }
810
811 void BKE_scene_collections_iterator_end(struct BLI_Iterator *iter)
812 {
813         SceneCollectionsIteratorData *data = iter->data;
814
815         if (data) {
816                 if (data->array) {
817                         MEM_freeN(data->array);
818                 }
819                 MEM_freeN(data);
820         }
821         iter->valid = false;
822 }
823
824
825 /* scene objects iteractor */
826
827 typedef struct SceneObjectsIteratorData {
828         GSet *visited;
829         LinkData *link_next;
830         BLI_Iterator scene_collection_iter;
831 } SceneObjectsIteratorData;
832
833 void BKE_scene_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
834 {
835         Scene *scene = data_in;
836         SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __func__);
837         iter->data = data;
838
839         /* lookup list ot make sure each object is object called once */
840         data->visited = BLI_gset_ptr_new(__func__);
841
842         /* we wrap the scenecollection iterator here to go over the scene collections */
843         BKE_scene_collections_iterator_begin(&data->scene_collection_iter, scene);
844
845         SceneCollection *sc = data->scene_collection_iter.current;
846         if (sc->objects.first != NULL) {
847                 iter->current = ((LinkData *)sc->objects.first)->data;
848         }
849         else {
850                 BKE_scene_objects_iterator_next(iter);
851         }
852 }
853
854 /**
855  * Gets the first unique object in the sequence
856  */
857 static LinkData *object_base_unique(GSet *gs, LinkData *link)
858 {
859         for (; link != NULL; link = link->next) {
860                 Object *ob = link->data;
861                 void **ob_key_p;
862                 if (!BLI_gset_ensure_p_ex(gs, ob, &ob_key_p)) {
863                         *ob_key_p = ob;
864                         return link;
865                 }
866         }
867         return NULL;
868 }
869
870 void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
871 {
872         SceneObjectsIteratorData *data = iter->data;
873         LinkData *link = data->link_next ? object_base_unique(data->visited, data->link_next) : NULL;
874
875         if (link) {
876                 data->link_next = link->next;
877                 iter->current = link->data;
878         }
879         else {
880                 /* if this is the last object of this ListBase look at the next SceneCollection */
881                 SceneCollection *sc;
882                 BKE_scene_collections_iterator_next(&data->scene_collection_iter);
883                 do {
884                         sc = data->scene_collection_iter.current;
885                         /* get the first unique object of this collection */
886                         LinkData *new_link = object_base_unique(data->visited, sc->objects.first);
887                         if (new_link) {
888                                 data->link_next = new_link->next;
889                                 iter->current = new_link->data;
890                                 return;
891                         }
892                         BKE_scene_collections_iterator_next(&data->scene_collection_iter);
893                 } while (data->scene_collection_iter.valid);
894
895                 if (!data->scene_collection_iter.valid) {
896                         iter->valid = false;
897                 }
898         }
899 }
900
901 void BKE_scene_objects_iterator_end(BLI_Iterator *iter)
902 {
903         SceneObjectsIteratorData *data = iter->data;
904         if (data) {
905                 BKE_scene_collections_iterator_end(&data->scene_collection_iter);
906                 BLI_gset_free(data->visited, NULL);
907                 MEM_freeN(data);
908         }
909 }