Blender V5.0
blenkernel/intern/layer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9/* Allow using deprecated functionality for .blend file I/O. */
10#define DNA_DEPRECATED_ALLOW
11
12#include <atomic>
13#include <cstring>
14
15#include "CLG_log.h"
16
17#include "BLI_listbase.h"
18#include "BLI_mempool.h"
19#include "BLI_string.h"
20#include "BLI_string_utf8.h"
21#include "BLI_string_utils.hh"
22#include "BLI_threads.h"
23#include "BLT_translation.hh"
24
25#include "BKE_animsys.h"
26#include "BKE_collection.hh"
27#include "BKE_freestyle.h"
28#include "BKE_idprop.hh"
29#include "BKE_layer.hh"
30#include "BKE_lib_id.hh"
31#include "BKE_library.hh"
32#include "BKE_main.hh"
33#include "BKE_node.hh"
35#include "BKE_node_runtime.hh"
36#include "BKE_object.hh"
37
38#include "DNA_ID.h"
40#include "DNA_defaults.h"
41#include "DNA_layer_types.h"
42#include "DNA_node_types.h"
43#include "DNA_object_types.h"
44#include "DNA_scene_types.h"
45#include "DNA_space_types.h"
46#include "DNA_view3d_types.h"
48#include "DNA_world_types.h"
49
50#include "DEG_depsgraph.hh"
53
54#include "DRW_engine.hh"
55
56#include "RE_engine.h"
57
58#include "MEM_guardedalloc.h"
59
60#include "BLO_read_write.hh"
61
62static CLG_LogRef LOG = {"object.layer"};
63
64/* Set of flags which are dependent on a collection settings. */
70
71/* prototype */
72static void object_bases_iterator_next(BLI_Iterator *iter, const int flag);
73
74/* -------------------------------------------------------------------- */
77
79{
80 LayerCollection *lc = MEM_callocN<LayerCollection>("Collection Base");
81 lc->collection = collection;
83 BLI_addtail(lb_parent, lc);
84
85 return lc;
86}
87
88static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc)
89{
90 if (lc == view_layer->active_collection) {
91 view_layer->active_collection = nullptr;
92 }
93
95 layer_collection_free(view_layer, nlc);
96 MEM_freeN(nlc);
97 }
99}
100
102{
103 Base *base = MEM_callocN<Base>("Object Base");
104 base->object = ob;
105 base->local_view_bits = ~0;
106 if (ob->base_flag & BASE_SELECTED) {
107 base->flag |= BASE_SELECTED;
108 }
109 return base;
110}
111
113
114/* -------------------------------------------------------------------- */
117
118/* RenderLayer */
119
121{
122 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
123 if (!(view_layer->flag & VIEW_LAYER_RENDER)) {
124 return view_layer;
125 }
126 }
127
129 return static_cast<ViewLayer *>(scene->view_layers.first);
130}
131
133{
134 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
135 if (view_layer->flag & VIEW_LAYER_RENDER) {
136 return view_layer;
137 }
138 }
139
141 return static_cast<ViewLayer *>(scene->view_layers.first);
142}
143
144ViewLayer *BKE_view_layer_find(const Scene *scene, const char *layer_name)
145{
146 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
147 if (STREQ(view_layer->name, layer_name)) {
148 return view_layer;
149 }
150 }
151
152 return nullptr;
153}
154
156{
158 return static_cast<ViewLayer *>(scene->view_layers.first);
159}
160
161static ViewLayer *view_layer_add(const char *name)
162{
163 if (!name) {
164 name = DATA_("ViewLayer");
165 }
166
167 ViewLayer *view_layer = MEM_callocN<ViewLayer>("View Layer");
168 *view_layer = *DNA_struct_default_get(ViewLayer);
169 STRNCPY_UTF8(view_layer->name, name);
170
172
173 return view_layer;
174}
175
176static void layer_collection_exclude_all(LayerCollection *layer_collection)
177{
178 LayerCollection *sub_collection = static_cast<LayerCollection *>(
179 layer_collection->layer_collections.first);
180 for (; sub_collection != nullptr; sub_collection = sub_collection->next) {
181 sub_collection->flag |= LAYER_COLLECTION_EXCLUDE;
182 layer_collection_exclude_all(sub_collection);
183 }
184}
185
187 const char *name,
188 ViewLayer *view_layer_source,
189 const int type)
190{
191 ViewLayer *view_layer_new;
192
193 if (view_layer_source) {
194 name = view_layer_source->name;
195 }
196
197 switch (type) {
198 default:
199 case VIEWLAYER_ADD_NEW: {
200 view_layer_new = view_layer_add(name);
201 BLI_addtail(&scene->view_layers, view_layer_new);
202 BKE_layer_collection_sync(scene, view_layer_new);
203 break;
204 }
205 case VIEWLAYER_ADD_COPY: {
206 /* Allocate and copy view layer data */
207 view_layer_new = MEM_callocN<ViewLayer>("View Layer");
208 *view_layer_new = *view_layer_source;
209 BKE_view_layer_copy_data(scene, scene, view_layer_new, view_layer_source, 0);
210 BLI_addtail(&scene->view_layers, view_layer_new);
211
212 STRNCPY_UTF8(view_layer_new->name, name);
213 break;
214 }
215 case VIEWLAYER_ADD_EMPTY: {
216 view_layer_new = view_layer_add(name);
217 BLI_addtail(&scene->view_layers, view_layer_new);
218
219 /* Initialize layer-collections. */
220 BKE_layer_collection_sync(scene, view_layer_new);
222 static_cast<LayerCollection *>(view_layer_new->layer_collections.first));
223
224 /* Update collections after changing visibility */
225 BKE_layer_collection_sync(scene, view_layer_new);
226 break;
227 }
228 }
229
230 /* unique name */
232 view_layer_new,
233 DATA_("ViewLayer"),
234 '_',
236 sizeof(view_layer_new->name));
237
238 return view_layer_new;
239}
240
242{
243 BKE_view_layer_free_ex(view_layer, true);
244}
245
246void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
247{
249
250 BLI_freelistN(&view_layer->aovs);
251 view_layer->active_aov = nullptr;
252 BLI_freelistN(&view_layer->lightgroups);
253 view_layer->active_lightgroup = nullptr;
254
255 /* Cannot use MEM_SAFE_FREE, as #SceneStats type is only forward-declared in `DNA_layer_types.h`
256 */
257 if (view_layer->stats) {
258 MEM_freeN(static_cast<void *>(view_layer->stats));
259 view_layer->stats = nullptr;
260 }
261
262 BKE_freestyle_config_free(&view_layer->freestyle_config, do_id_user);
263
264 if (view_layer->id_properties) {
265 IDP_FreeProperty_ex(view_layer->id_properties, do_id_user);
266 }
267 if (view_layer->system_properties) {
268 IDP_FreeProperty_ex(view_layer->system_properties, do_id_user);
269 }
270
272
273 MEM_freeN(view_layer);
274}
275
277{
278 view_layer->basact = nullptr;
279
280 BLI_freelistN(&view_layer->object_bases);
281
282 if (view_layer->object_bases_hash) {
283 BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
284 }
285
287 layer_collection_free(view_layer, lc);
288 MEM_freeN(lc);
289 }
291}
292
293void BKE_view_layer_selected_objects_tag(const Scene *scene, ViewLayer *view_layer, const int tag)
294{
295 BKE_view_layer_synced_ensure(scene, view_layer);
297 if ((base->flag & BASE_SELECTED) != 0) {
298 base->object->flag |= tag;
299 }
300 else {
301 base->object->flag &= ~tag;
302 }
303 }
304}
305
307{
308 LISTBASE_FOREACH (LayerCollection *, lcn, lb) {
309 if (lcn == lc) {
310 return true;
311 }
312 if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
313 return true;
314 }
315 }
316 return false;
317}
318
320{
321 BKE_view_layer_synced_ensure(scene, view_layer);
323 if (base->object->type == OB_CAMERA) {
324 return base->object;
325 }
326 }
327
328 return nullptr;
329}
330
332{
333 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
334 if (find_scene_collection_in_scene_collections(&view_layer->layer_collections, lc)) {
335 return view_layer;
336 }
337 }
338
339 return nullptr;
340}
341
342/* Base */
343
344static void view_layer_bases_hash_create(ViewLayer *view_layer, const bool do_base_duplicates_fix)
345{
346 static blender::Mutex hash_lock;
347
348 if (view_layer->object_bases_hash == nullptr) {
349 std::scoped_lock lock(hash_lock);
350
351 if (view_layer->object_bases_hash == nullptr) {
353
354 LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
355 if (base->object) {
356 void **val_pp;
357 if (!BLI_ghash_ensure_p(hash, base->object, &val_pp)) {
358 *val_pp = base;
359 }
360 /* The same object has several bases.
361 *
362 * In normal cases this is a serious bug, but this is a common situation when remapping
363 * an object into another one already present in the same View Layer. While ideally we
364 * would process this case separately, for performances reasons it makes more sense to
365 * tackle it here. */
366 else if (do_base_duplicates_fix) {
367 if (view_layer->basact == base) {
368 view_layer->basact = nullptr;
369 }
370 BLI_freelinkN(&view_layer->object_bases, base);
371 }
372 else {
374 "Object '%s' has more than one entry in view layer's object bases listbase",
375 base->object->id.name + 2);
376 }
377 }
378 }
379
380 /* Assign pointer only after hash is complete. */
381 view_layer->object_bases_hash = hash;
382 }
383 }
384}
385
387{
388 BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
389 "View layer out of sync, invoke BKE_view_layer_synced_ensure.");
390 if (!view_layer->object_bases_hash) {
391 view_layer_bases_hash_create(view_layer, false);
392 }
393
394 return static_cast<Base *>(BLI_ghash_lookup(view_layer->object_bases_hash, ob));
395}
396
397void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
398{
399 BLI_assert(scene);
400 BLI_assert(view_layer);
401
402 BKE_view_layer_synced_ensure(scene, view_layer);
404 base->flag &= ~BASE_SELECTED;
405 }
406}
407
409{
410 view_layer->basact = selbase;
411 if ((selbase->flag & BASE_SELECTABLE) != 0) {
412 selbase->flag |= BASE_SELECTED;
413 }
414}
415
417
418/* -------------------------------------------------------------------- */
421
422static void layer_aov_copy_data(ViewLayer *view_layer_dst,
423 const ViewLayer *view_layer_src,
424 ListBase *aovs_dst,
425 const ListBase *aovs_src)
426{
427 BLI_duplicatelist(aovs_dst, aovs_src);
428
429 ViewLayerAOV *aov_dst = static_cast<ViewLayerAOV *>(aovs_dst->first);
430 const ViewLayerAOV *aov_src = static_cast<const ViewLayerAOV *>(aovs_src->first);
431
432 while (aov_dst != nullptr) {
433 BLI_assert(aov_src);
434 if (aov_src == view_layer_src->active_aov) {
435 view_layer_dst->active_aov = aov_dst;
436 }
437
438 aov_dst = aov_dst->next;
439 aov_src = aov_src->next;
440 }
441}
442
443static void layer_lightgroup_copy_data(ViewLayer *view_layer_dst,
444 const ViewLayer *view_layer_src,
445 ListBase *lightgroups_dst,
446 const ListBase *lightgroups_src)
447{
448 if (lightgroups_src != nullptr) {
449 BLI_duplicatelist(lightgroups_dst, lightgroups_src);
450 }
451
452 ViewLayerLightgroup *lightgroup_dst = static_cast<ViewLayerLightgroup *>(lightgroups_dst->first);
453 const ViewLayerLightgroup *lightgroup_src = static_cast<const ViewLayerLightgroup *>(
454 lightgroups_src->first);
455
456 while (lightgroup_dst != nullptr) {
457 BLI_assert(lightgroup_src);
458 if (lightgroup_src == view_layer_src->active_lightgroup) {
459 view_layer_dst->active_lightgroup = lightgroup_dst;
460 }
461
462 lightgroup_dst = lightgroup_dst->next;
463 lightgroup_src = lightgroup_src->next;
464 }
465}
466
467static void layer_collections_copy_data(ViewLayer *view_layer_dst,
468 const ViewLayer *view_layer_src,
469 ListBase *layer_collections_dst,
470 const ListBase *layer_collections_src)
471{
472 BLI_duplicatelist(layer_collections_dst, layer_collections_src);
473
474 LayerCollection *layer_collection_dst = static_cast<LayerCollection *>(
475 layer_collections_dst->first);
476 const LayerCollection *layer_collection_src = static_cast<const LayerCollection *>(
477 layer_collections_src->first);
478
479 while (layer_collection_dst != nullptr) {
480 layer_collections_copy_data(view_layer_dst,
481 view_layer_src,
482 &layer_collection_dst->layer_collections,
483 &layer_collection_src->layer_collections);
484
485 if (layer_collection_src == view_layer_src->active_collection) {
486 view_layer_dst->active_collection = layer_collection_dst;
487 }
488
489 layer_collection_dst = layer_collection_dst->next;
490 layer_collection_src = layer_collection_src->next;
491 }
492}
493
495 const Scene * /*scene_src*/,
496 ViewLayer *view_layer_dst,
497 const ViewLayer *view_layer_src,
498 const int flag)
499{
500 if (view_layer_dst->id_properties != nullptr) {
501 view_layer_dst->id_properties = IDP_CopyProperty_ex(view_layer_dst->id_properties, flag);
502 }
503 if (view_layer_dst->system_properties != nullptr) {
504 view_layer_dst->system_properties = IDP_CopyProperty_ex(view_layer_dst->system_properties,
505 flag);
506 }
508 &view_layer_dst->freestyle_config, &view_layer_src->freestyle_config, flag);
509
510 view_layer_dst->stats = nullptr;
511
512 /* Clear temporary data. */
513 view_layer_dst->object_bases_array = nullptr;
514 view_layer_dst->object_bases_hash = nullptr;
515
516 /* Copy layer collections and object bases. */
517 /* Inline #BLI_duplicatelist and update the active base. */
518 BLI_listbase_clear(&view_layer_dst->object_bases);
519 BLI_assert_msg((view_layer_src->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
520 "View Layer Object Base out of sync, invoke BKE_view_layer_synced_ensure.");
521 LISTBASE_FOREACH (const Base *, base_src, &view_layer_src->object_bases) {
522 Base *base_dst = static_cast<Base *>(MEM_dupallocN(base_src));
523 BLI_addtail(&view_layer_dst->object_bases, base_dst);
524 if (view_layer_src->basact == base_src) {
525 view_layer_dst->basact = base_dst;
526 }
527 }
528
529 view_layer_dst->active_collection = nullptr;
530 layer_collections_copy_data(view_layer_dst,
531 view_layer_src,
532 &view_layer_dst->layer_collections,
533 &view_layer_src->layer_collections);
534
535 LayerCollection *lc_scene_dst = static_cast<LayerCollection *>(
536 view_layer_dst->layer_collections.first);
537 lc_scene_dst->collection = scene_dst->master_collection;
538
539 BLI_listbase_clear(&view_layer_dst->aovs);
541 view_layer_dst, view_layer_src, &view_layer_dst->aovs, &view_layer_src->aovs);
542
543 BLI_listbase_clear(&view_layer_dst->lightgroups);
545 view_layer_dst, view_layer_src, &view_layer_dst->lightgroups, &view_layer_src->lightgroups);
546
548 id_us_plus((ID *)view_layer_dst->mat_override);
549 }
550}
551
552void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, const char *newname)
553{
554 char oldname[sizeof(view_layer->name)];
555
556 STRNCPY(oldname, view_layer->name);
557
558 STRNCPY_UTF8(view_layer->name, newname);
560 view_layer,
561 DATA_("ViewLayer"),
562 '.',
564 sizeof(view_layer->name));
565
566 if (scene->compositing_node_group) {
567 int index = BLI_findindex(&scene->view_layers, view_layer);
568
569 for (bNode *node : scene->compositing_node_group->all_nodes()) {
570 if (node->type_legacy == CMP_NODE_R_LAYERS && node->id == nullptr) {
571 if (node->custom1 == index) {
572 STRNCPY_UTF8(node->name, view_layer->name);
573 }
574 }
575 }
576 }
577
578 /* Fix all the animation data and windows which may link to this. */
579 BKE_animdata_fix_paths_rename_all(nullptr, "view_layers", oldname, view_layer->name);
580
581 /* WM can be missing on startup. */
582 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
583 if (wm) {
584 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
585 if (win->scene == scene && STREQ(win->view_layer_name, oldname)) {
586 STRNCPY_UTF8(win->view_layer_name, view_layer->name);
587 }
588 }
589 }
590
591 /* Dependency graph uses view layer name based lookups. */
593}
594
595/* LayerCollection */
596
600static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
601{
603 if (*i == number) {
604 return lc;
605 }
606
607 (*i)++;
608 }
609
611 LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
612 if (lc_nested) {
613 return lc_nested;
614 }
615 }
616 return nullptr;
617}
618
623{
624 if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
625 return true;
626 }
627
628 /* Check visibility restriction flags */
630 return true;
631 }
632
633 /* Restriction flags stay set, so we need to check parents */
634 CollectionParent *parent = static_cast<CollectionParent *>(
635 lc->collection->runtime->parents.first);
636
637 if (parent) {
639
640 return lc && layer_collection_hidden(view_layer, lc);
641 }
642
643 return false;
644}
645
647{
648 int i = 0;
649 return collection_from_index(&view_layer->layer_collections, index, &i);
650}
651
653{
654 return view_layer->active_collection;
655}
656
658{
659 if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
660 return false;
661 }
662
663 view_layer->active_collection = lc;
664 return true;
665}
666
668{
669 CollectionParent *parent = static_cast<CollectionParent *>(
670 lc->collection->runtime->parents.first);
671
672 if (parent) {
674 }
675 else {
676 lc = nullptr;
677 }
678
679 /* Don't activate excluded or hidden collections to prevent creating objects in a hidden
680 * collection from the UI */
681 if (lc && layer_collection_hidden(view_layer, lc)) {
682 return BKE_layer_collection_activate_parent(view_layer, lc);
683 }
684
685 if (!lc) {
686 lc = static_cast<LayerCollection *>(view_layer->layer_collections.first);
687 }
688
689 view_layer->active_collection = lc;
690 return lc;
691}
692
696static int collection_count(const ListBase *lb)
697{
698 int i = 0;
699 LISTBASE_FOREACH (const LayerCollection *, lc, lb) {
700 i += collection_count(&lc->layer_collections) + 1;
701 }
702 return i;
703}
704
706{
707 return collection_count(&view_layer->layer_collections);
708}
709
713static int index_from_collection(ListBase *lb, const LayerCollection *lc, int *i)
714{
715 LISTBASE_FOREACH (LayerCollection *, lcol, lb) {
716 if (lcol == lc) {
717 return *i;
718 }
719
720 (*i)++;
721 }
722
723 LISTBASE_FOREACH (LayerCollection *, lcol, lb) {
724 int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
725 if (i_nested != -1) {
726 return i_nested;
727 }
728 }
729 return -1;
730}
731
733{
734 int i = 0;
735 return index_from_collection(&view_layer->layer_collections, lc, &i);
736}
737
739
740/* -------------------------------------------------------------------- */
775
776/* NOTE: This can also be modified from several threads (e.g. during depsgraph evaluation), leading
777 * to transitional big numbers. */
778static std::atomic<int32_t> no_resync = 0;
779/* Maximum allowed levels of re-entrant calls to #BKE_layer_collection_resync_forbid. */
780[[maybe_unused]] static constexpr int no_resync_recurse_max = 16 * 256;
781
788
795
798
799 /* Temp data used to generate a queue during valid layer search. See
800 * #layer_collection_resync_find. */
802
803 /* LayerCollection and Collection wrapped by this data. */
806
807 /* Hierarchical relationships in the old, existing ViewLayer state (except for newly created
808 * layers). */
811
812 /* This layer still points to a valid collection. */
814 /* This layer is still valid as a parent, i.e. at least one of its original layer children is
815 * usable and matches one of its current children collections. */
817 /* This layer is still valid as a child, i.e. its original layer parent is usable and matches one
818 * of its current parents collections. */
820 /* This layer is still fully valid in the new collection hierarchy, i.e. itself and all of its
821 * parents fully match the current collection hierarchy.
822 * OR
823 * This layer has already been re-used to match the new collections hierarchy. */
825};
826
828 LayerCollectionResync *parent_layer_resync, LayerCollection *layer, BLI_mempool *mempool)
829{
830 LayerCollectionResync *layer_resync = static_cast<LayerCollectionResync *>(
831 BLI_mempool_calloc(mempool));
832
833 layer_resync->layer = layer;
834 layer_resync->collection = layer->collection;
835 layer_resync->parent_layer_resync = parent_layer_resync;
836 if (parent_layer_resync != nullptr) {
837 BLI_addtail(&parent_layer_resync->children_layer_resync, layer_resync);
838 }
839
840 layer_resync->is_usable = (layer->collection != nullptr);
841 layer_resync->is_valid_as_child =
842 layer_resync->is_usable && (parent_layer_resync == nullptr ||
843 (parent_layer_resync->is_usable &&
844 BLI_findptr(&parent_layer_resync->layer->collection->children,
845 layer->collection,
846 offsetof(CollectionChild, collection)) != nullptr));
847 if (layer_resync->is_valid_as_child) {
848 layer_resync->is_used = parent_layer_resync != nullptr ? parent_layer_resync->is_used : true;
849 }
850 else {
851 layer_resync->is_used = false;
852 }
853
855 layer_resync->is_valid_as_parent = layer_resync->is_usable;
856 }
857 else {
858 LISTBASE_FOREACH (LayerCollection *, child_layer, &layer->layer_collections) {
860 layer_resync, child_layer, mempool);
861 if (layer_resync->is_usable && child_layer_resync->is_valid_as_child) {
862 layer_resync->is_valid_as_parent = true;
863 }
864 }
865 }
866
868 "Old LayerCollection for %s is...\n\tusable: %d\n\tvalid parent: %d\n\tvalid child: "
869 "%d\n\tused: %d\n",
870 layer_resync->collection ? layer_resync->collection->id.name : "<NONE>",
871 layer_resync->is_usable,
872 layer_resync->is_valid_as_parent,
873 layer_resync->is_valid_as_child,
874 layer_resync->is_used);
875
876 return layer_resync;
877}
878
880 Collection *child_collection)
881{
882 /* Given the given parent, valid layer collection, find in the old hierarchy the best possible
883 * unused layer matching the given child collection.
884 *
885 * This uses the following heuristics:
886 * - Prefer a layer descendant of the given parent one if possible.
887 * - Prefer a layer as closely related as possible from the given parent.
888 * - Do not used layers that are not head (highest possible ancestor) of a local valid hierarchy
889 * branch, since we can assume we could then re-use its ancestor instead.
890 *
891 * A queue is used to ensure this order of preferences.
892 */
893
894 BLI_assert(layer_resync->collection != child_collection);
895 BLI_assert(child_collection != nullptr);
896
897 LayerCollectionResync *current_layer_resync = nullptr;
898 LayerCollectionResync *root_layer_resync = layer_resync;
899
900 LayerCollectionResync *queue_head = layer_resync, *queue_tail = layer_resync;
901 layer_resync->queue_next = nullptr;
902
903 while (queue_head != nullptr) {
904 current_layer_resync = queue_head;
905 queue_head = current_layer_resync->queue_next;
906
907 if (current_layer_resync->collection == child_collection &&
908 (current_layer_resync->parent_layer_resync == layer_resync ||
909 (!current_layer_resync->is_used && !current_layer_resync->is_valid_as_child)))
910 {
911 /* This layer is a valid candidate, because its collection matches the seeked one, AND:
912 * - It is a direct child of the initial given parent ('unchanged hierarchy' case), OR
913 * - It is not currently used, and not part of a valid hierarchy (sub-)chain.
914 */
915 break;
916 }
917
918 /* Else, add all its direct children for further searching. */
920 LayerCollectionResync *, child_layer_resync, &current_layer_resync->children_layer_resync)
921 {
922 /* Add to tail of the queue. */
923 queue_tail->queue_next = child_layer_resync;
924 child_layer_resync->queue_next = nullptr;
925 queue_tail = child_layer_resync;
926 if (queue_head == nullptr) {
927 queue_head = queue_tail;
928 }
929 }
930
931 /* If all descendants from current layer have been processed, go one step higher and
932 * process all of its other siblings. */
933 if (queue_head == nullptr && root_layer_resync->parent_layer_resync != nullptr) {
935 sibling_layer_resync,
936 &root_layer_resync->parent_layer_resync->children_layer_resync)
937 {
938 if (sibling_layer_resync == root_layer_resync) {
939 continue;
940 }
941 /* Add to tail of the queue. */
942 queue_tail->queue_next = sibling_layer_resync;
943 sibling_layer_resync->queue_next = nullptr;
944 queue_tail = sibling_layer_resync;
945 if (queue_head == nullptr) {
946 queue_head = queue_tail;
947 }
948 }
949 root_layer_resync = root_layer_resync->parent_layer_resync;
950 }
951
952 current_layer_resync = nullptr;
953 }
954
955 return current_layer_resync;
956}
957
959 LayerCollectionResync *layer_resync)
960{
962 LayerCollectionResync *, child_layer_resync, &layer_resync->children_layer_resync)
963 {
964 layer_collection_resync_unused_layers_free(view_layer, child_layer_resync);
965 }
966
967 if (!layer_resync->is_used) {
969 "Freeing unused LayerCollection for %s",
970 layer_resync->collection != nullptr ? layer_resync->collection->id.name :
971 "<Deleted Collection>");
972
973 if (layer_resync->layer == view_layer->active_collection) {
974 view_layer->active_collection = nullptr;
975 }
976
977 /* We do not want to go recursive here, this is handled through the LayerCollectionResync data
978 * wrapper. */
979 MEM_freeN(layer_resync->layer);
980 layer_resync->layer = nullptr;
981 layer_resync->collection = nullptr;
982 layer_resync->is_usable = false;
983 }
984}
985
987{
988 view_layer->flag |= VIEW_LAYER_OUT_OF_SYNC;
989}
990
991void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
992{
993 BLI_assert(scene);
994 BLI_assert(view_layer);
995
996 if (view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) {
997 BKE_layer_collection_sync(scene, view_layer);
998 view_layer->flag &= ~VIEW_LAYER_OUT_OF_SYNC;
999 }
1000}
1001
1003{
1004 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1005 BKE_view_layer_synced_ensure(scene, view_layer);
1006 }
1007}
1008
1010{
1011 for (const Scene *scene = static_cast<const Scene *>(bmain->scenes.first); scene;
1012 scene = static_cast<const Scene *>(scene->id.next))
1013 {
1015 }
1016
1017 /* NOTE: This is not (yet?) covered by the dirty tag and deferred re-sync system. */
1019}
1020
1022 LayerCollection *layer,
1023 ListBase *r_lb_new_object_bases,
1024 const short collection_restrict,
1025 const short layer_restrict,
1026 const ushort local_collections_bits)
1027{
1028 /* No need to sync objects if the collection is excluded. */
1029 if ((layer->flag & LAYER_COLLECTION_EXCLUDE) != 0) {
1030 return;
1031 }
1032
1034 if (cob->ob == nullptr) {
1035 continue;
1036 }
1037
1038 /* Tag linked object as a weak reference so we keep the object
1039 * base pointer on file load and remember hidden state. */
1040 id_lib_indirect_weak_link(&cob->ob->id);
1041
1042 void **base_p;
1043 Base *base;
1044 if (BLI_ghash_ensure_p(view_layer->object_bases_hash, cob->ob, &base_p)) {
1045 /* Move from old base list to new base list. Base might have already
1046 * been moved to the new base list and the first/last test ensure that
1047 * case also works. */
1048 base = static_cast<Base *>(*base_p);
1049 if (!ELEM(base, r_lb_new_object_bases->first, r_lb_new_object_bases->last)) {
1050 BLI_remlink(&view_layer->object_bases, base);
1051 BLI_addtail(r_lb_new_object_bases, base);
1052 }
1053 }
1054 else {
1055 /* Create new base. */
1056 base = object_base_new(cob->ob);
1057 base->local_collections_bits = local_collections_bits;
1058 *base_p = base;
1059 BLI_addtail(r_lb_new_object_bases, base);
1060 }
1061
1062 if ((collection_restrict & COLLECTION_HIDE_VIEWPORT) == 0) {
1065 if ((layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
1067 }
1068 if ((collection_restrict & COLLECTION_HIDE_SELECT) == 0) {
1070 }
1071 }
1072
1073 if ((collection_restrict & COLLECTION_HIDE_RENDER) == 0) {
1075 }
1076
1077 /* Holdout and indirect only */
1078 if (layer->flag & LAYER_COLLECTION_HOLDOUT) {
1080 }
1081 if (layer->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
1083 }
1084
1086 }
1087}
1088
1089static void layer_collection_sync(ViewLayer *view_layer,
1090 LayerCollectionResync *layer_resync,
1091 BLI_mempool *layer_resync_mempool,
1092 ListBase *r_lb_new_object_bases,
1093 const short parent_layer_flag,
1094 const short parent_collection_restrict,
1095 const short parent_layer_restrict,
1096 const ushort parent_local_collections_bits)
1097{
1098 /* This function assumes current 'parent' layer collection is already fully (re)synced and valid
1099 * regarding current Collection hierarchy.
1100 *
1101 * It will process all the children collections of the collection from the given 'parent' layer,
1102 * re-use or create layer collections for each of them, and ensure orders also match.
1103 *
1104 * Then it will ensure that the objects owned by the given parent collection have a proper base.
1105 *
1106 * NOTE: This process is recursive.
1107 */
1108
1109 /* Temporary storage for all valid (new or reused) children layers. */
1110 ListBase new_lb_layer = {nullptr, nullptr};
1111
1112 BLI_assert(layer_resync->is_used);
1113
1114 uint64_t skipped_children = 0;
1115 LISTBASE_FOREACH (CollectionChild *, child, &layer_resync->collection->children) {
1116 Collection *child_collection = child->collection;
1117 /* Collection relations may not have rebuild yet. */
1118 if (child_collection == nullptr) {
1119 skipped_children++;
1120 continue;
1121 }
1122 LayerCollectionResync *child_layer_resync = layer_collection_resync_find(layer_resync,
1123 child_collection);
1124
1125 if (child_layer_resync != nullptr) {
1126 BLI_assert(child_layer_resync->collection != nullptr);
1127 BLI_assert(child_layer_resync->layer != nullptr);
1128 BLI_assert(child_layer_resync->is_usable);
1129
1130 if (child_layer_resync->is_used) {
1131 CLOG_DEBUG(&LOG,
1132 "Found same existing LayerCollection for %s as child of %s",
1133 child_collection->id.name,
1134 layer_resync->collection->id.name);
1135 }
1136 else {
1137 CLOG_DEBUG(&LOG,
1138 "Found a valid unused LayerCollection for %s as child of %s, re-using it",
1139 child_collection->id.name,
1140 layer_resync->collection->id.name);
1141 }
1142
1143 child_layer_resync->is_used = true;
1144
1145 /* NOTE: Do not move the resync wrapper to match the new layer hierarchy, so that the old
1146 * parenting info remains available. In case a search for a valid layer in the children of
1147 * the current is required again, the old parenting hierarchy is needed as reference, not the
1148 * new one.
1149 */
1151 child_layer_resync->layer);
1152 BLI_addtail(&new_lb_layer, child_layer_resync->layer);
1153 }
1154 else {
1155 CLOG_DEBUG(&LOG,
1156 "No available LayerCollection for %s as child of %s, creating a new one",
1157 child_collection->id.name,
1158 layer_resync->collection->id.name);
1159
1160 LayerCollection *child_layer = layer_collection_add(&new_lb_layer, child_collection);
1161 child_layer->flag = parent_layer_flag;
1162
1163 child_layer_resync = static_cast<LayerCollectionResync *>(
1164 BLI_mempool_calloc(layer_resync_mempool));
1165 child_layer_resync->collection = child_collection;
1166 child_layer_resync->layer = child_layer;
1167 child_layer_resync->is_usable = true;
1168 child_layer_resync->is_used = true;
1169 child_layer_resync->is_valid_as_child = true;
1170 child_layer_resync->is_valid_as_parent = true;
1171 /* NOTE: Needs to be added to the layer_resync hierarchy so that the resync wrapper gets
1172 * freed at the end. */
1173 child_layer_resync->parent_layer_resync = layer_resync;
1174 BLI_addtail(&layer_resync->children_layer_resync, child_layer_resync);
1175 }
1176
1177 LayerCollection *child_layer = child_layer_resync->layer;
1178
1179 const ushort child_local_collections_bits = parent_local_collections_bits &
1180 child_layer->local_collections_bits;
1181
1182 /* Tag linked collection as a weak reference so we keep the layer
1183 * collection pointer on file load and remember exclude state. */
1184 id_lib_indirect_weak_link(&child_collection->id);
1185
1186 /* Collection restrict is inherited. */
1187 short child_collection_restrict = parent_collection_restrict;
1188 short child_layer_restrict = parent_layer_restrict;
1189 if (!(child_collection->flag & COLLECTION_IS_MASTER)) {
1190 child_collection_restrict |= child_collection->flag;
1191 child_layer_restrict |= child_layer->flag;
1192 }
1193
1194 /* Sync child collections. */
1195 layer_collection_sync(view_layer,
1196 child_layer_resync,
1197 layer_resync_mempool,
1198 r_lb_new_object_bases,
1199 child_layer->flag,
1200 child_collection_restrict,
1201 child_layer_restrict,
1202 child_local_collections_bits);
1203
1204 /* Layer collection exclude is not inherited. */
1205 child_layer->runtime_flag = 0;
1206 if (child_layer->flag & LAYER_COLLECTION_EXCLUDE) {
1207 continue;
1208 }
1209
1210 /* We separate restrict viewport and visible view layer because a layer collection can be
1211 * hidden in the view layer yet (locally) visible in a viewport (if it is not restricted). */
1212 if (child_collection_restrict & COLLECTION_HIDE_VIEWPORT) {
1214 }
1215
1216 if (((child_layer->runtime_flag & LAYER_COLLECTION_HIDE_VIEWPORT) == 0) &&
1217 ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0))
1218 {
1220 }
1221
1222 if (!BLI_listbase_is_empty(&child_collection->exporters) &&
1223 !(ID_IS_LINKED(&child_collection->id) || ID_IS_OVERRIDE_LIBRARY(&child_collection->id)))
1224 {
1226 }
1227 }
1228
1229 /* Replace layer collection list with new one. */
1230 layer_resync->layer->layer_collections = new_lb_layer;
1231 BLI_assert(BLI_listbase_count(&layer_resync->collection->children) - skipped_children ==
1232 BLI_listbase_count(&new_lb_layer));
1233 UNUSED_VARS_NDEBUG(skipped_children);
1234
1235 /* Update bases etc. for objects. */
1237 layer_resync->layer,
1238 r_lb_new_object_bases,
1239 parent_collection_restrict,
1240 parent_layer_restrict,
1241 parent_local_collections_bits);
1242}
1243
1244#ifndef NDEBUG
1246{
1247 bool is_valid = true;
1248
1249 if (layer == nullptr) {
1250 layer = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1251 }
1252
1253 /* Only check for a collection's objects if its layer is not excluded. */
1254 if ((layer->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1256 if (cob->ob == nullptr) {
1257 continue;
1258 }
1259 if (BLI_ghash_lookup(view_layer->object_bases_hash, cob->ob) == nullptr) {
1260 CLOG_FATAL(
1261 &LOG,
1262 "Object '%s' from collection '%s' has no entry in view layer's object bases cache",
1263 cob->ob->id.name + 2,
1264 layer->collection->id.name + 2);
1265 is_valid = false;
1266 break;
1267 }
1268 }
1269 }
1270
1271 if (is_valid) {
1272 LISTBASE_FOREACH (LayerCollection *, layer_child, &layer->layer_collections) {
1273 if (!view_layer_objects_base_cache_validate(view_layer, layer_child)) {
1274 is_valid = false;
1275 break;
1276 }
1277 }
1278 }
1279
1280 return is_valid;
1281}
1282#else
1283static bool view_layer_objects_base_cache_validate(ViewLayer * /*view_layer*/,
1284 LayerCollection * /*layer*/)
1285{
1286 return true;
1287}
1288#endif
1289
1291{
1292 LayerCollection *first_layer_collection = static_cast<LayerCollection *>(
1293 view_layer->layer_collections.first);
1294 if (BLI_listbase_count_at_most(&view_layer->layer_collections, 2) > 1 ||
1295 first_layer_collection->collection != scene->master_collection)
1296 {
1297 /* In some cases (from older files) we do have a master collection, but no matching layer,
1298 * instead all the children of the master collection have their layer collections in the
1299 * viewlayer's list. This is not a valid situation, add a layer for the master collection and
1300 * add all existing first-level layers as children of that new master layer. */
1301 ListBase layer_collections = view_layer->layer_collections;
1303 LayerCollection *master_layer_collection = layer_collection_add(&view_layer->layer_collections,
1304 scene->master_collection);
1305 master_layer_collection->layer_collections = layer_collections;
1306 }
1307}
1308
1309void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
1310{
1311 if (no_resync > 0) {
1312 return;
1313 }
1314
1315 if (!scene->master_collection) {
1316 /* Happens for old files that don't have versioning applied yet. */
1317 return;
1318 }
1319
1320 if (BLI_listbase_is_empty(&view_layer->layer_collections)) {
1321 /* In some cases (from older files, or when creating a new ViewLayer from
1322 * #BKE_view_layer_add), we do have a master collection, yet no matching layer. Create the
1323 * master one here, so that the rest of the code can work as expected. */
1325 }
1326
1327#ifndef NDEBUG
1328 {
1330 "ViewLayer's first level of children layer collections should always have "
1331 "exactly one item");
1332
1333 LayerCollection *first_layer_collection = static_cast<LayerCollection *>(
1334 view_layer->layer_collections.first);
1335 BLI_assert_msg(first_layer_collection->collection == scene->master_collection,
1336 "ViewLayer's first layer collection should always be the one for the scene's "
1337 "master collection");
1338 }
1339#endif
1340
1341 /* Free cache. */
1342 MEM_SAFE_FREE(view_layer->object_bases_array);
1343
1344 /* Create object to base hash if it does not exist yet. */
1345 if (!view_layer->object_bases_hash) {
1346 view_layer_bases_hash_create(view_layer, false);
1347 }
1348
1349 /* Clear visible and selectable flags to be reset. */
1350 LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1351 base->flag &= ~g_base_collection_flags;
1352 base->flag_from_collection &= ~g_base_collection_flags;
1353 }
1354
1355 /* Generate temporary data representing the old layers hierarchy, and how well it matches the
1356 * new collections hierarchy. */
1357 BLI_mempool *layer_resync_mempool = BLI_mempool_create(
1358 sizeof(LayerCollectionResync), 1024, 1024, BLI_MEMPOOL_NOP);
1360 nullptr,
1361 static_cast<LayerCollection *>(view_layer->layer_collections.first),
1362 layer_resync_mempool);
1363
1364 /* Clear the cached flag indicating if the view layer has a collection exporter set. */
1366
1367 /* Generate new layer connections and object bases when collections changed. */
1368 ListBase new_object_bases{};
1369 const short parent_exclude = 0, parent_restrict = 0, parent_layer_restrict = 0;
1370 layer_collection_sync(view_layer,
1371 master_layer_resync,
1372 layer_resync_mempool,
1373 &new_object_bases,
1374 parent_exclude,
1375 parent_restrict,
1376 parent_layer_restrict,
1377 ~0);
1378
1379 layer_collection_resync_unused_layers_free(view_layer, master_layer_resync);
1380 BLI_mempool_destroy(layer_resync_mempool);
1381 master_layer_resync = nullptr;
1382
1383 /* Any remaining object bases are to be removed. */
1384 LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1385 if (view_layer->basact == base) {
1386 view_layer->basact = nullptr;
1387 }
1388
1389 if (base->object) {
1390 /* Those asserts are commented, since they are too expensive to perform even in debug, as
1391 * this layer resync function currently gets called way too often. */
1392#if 0
1393 BLI_assert(BLI_findindex(&new_object_bases, base) == -1);
1394 BLI_assert(BLI_findptr(&new_object_bases, base->object, offsetof(Base, object)) == nullptr);
1395#endif
1396 BLI_ghash_remove(view_layer->object_bases_hash, base->object, nullptr, nullptr);
1397 }
1398 }
1399
1400 BLI_freelistN(&view_layer->object_bases);
1401 view_layer->object_bases = new_object_bases;
1402
1403 view_layer_objects_base_cache_validate(view_layer, nullptr);
1404
1405 LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1406 BKE_base_eval_flags(base);
1407 }
1408
1409 /* Always set a valid active collection. */
1411 if (active && layer_collection_hidden(view_layer, active)) {
1413 }
1414 else if (active == nullptr) {
1415 view_layer->active_collection = static_cast<LayerCollection *>(
1416 view_layer->layer_collections.first);
1417 }
1418}
1419
1421{
1422 if (no_resync > 0) {
1423 return;
1424 }
1425
1426 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1428 }
1429}
1430
1432{
1433 if (no_resync > 0) {
1434 return;
1435 }
1436
1437 /* TODO: if a single collection changed, figure out which
1438 * scenes it belongs to and only update those. */
1439
1440 /* TODO: optimize for file load so only linked collections get checked? */
1441
1442 for (const Scene *scene = static_cast<const Scene *>(bmain->scenes.first); scene;
1443 scene = static_cast<const Scene *>(scene->id.next))
1444 {
1446 }
1447
1449}
1450
1452{
1453 if (no_resync > 0) {
1454 return;
1455 }
1456
1457 /* On remapping of object or collection pointers free caches. */
1458 /* TODO: try to make this faster */
1459
1461
1462 for (Scene *scene = static_cast<Scene *>(bmain->scenes.first); scene;
1463 scene = static_cast<Scene *>(scene->id.next))
1464 {
1465 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1466 MEM_SAFE_FREE(view_layer->object_bases_array);
1467
1468 if (view_layer->object_bases_hash) {
1469 BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
1470 view_layer->object_bases_hash = nullptr;
1471 }
1472
1473 /* Directly re-create the mapping here, so that we can also deal with duplicates in
1474 * `view_layer->object_bases` list of bases properly. This is the only place where such
1475 * duplicates should be fixed, and not considered as a critical error. */
1476 view_layer_bases_hash_create(view_layer, true);
1477 }
1478
1479 DEG_id_tag_update_ex((Main *)bmain, &scene->master_collection->id, ID_RECALC_SYNC_TO_EVAL);
1480 DEG_id_tag_update_ex((Main *)bmain, &scene->id, ID_RECALC_SYNC_TO_EVAL);
1481 }
1482
1483 for (Collection *collection = static_cast<Collection *>(bmain->collections.first); collection;
1484 collection = static_cast<Collection *>(collection->id.next))
1485 {
1486 DEG_id_tag_update_ex((Main *)bmain, &collection->id, ID_RECALC_SYNC_TO_EVAL);
1487 }
1488
1490}
1491
1493
1494/* -------------------------------------------------------------------- */
1497
1499 ViewLayer *view_layer,
1500 LayerCollection *lc,
1501 bool deselect)
1502{
1504 return false;
1505 }
1506
1507 bool changed = false;
1508
1509 if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
1510 BKE_view_layer_synced_ensure(scene, view_layer);
1512 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1513
1514 if (base) {
1515 if (deselect) {
1516 if (base->flag & BASE_SELECTED) {
1517 base->flag &= ~BASE_SELECTED;
1518 changed = true;
1519 }
1520 }
1521 else {
1522 if ((base->flag & BASE_SELECTABLE) && !(base->flag & BASE_SELECTED)) {
1523 base->flag |= BASE_SELECTED;
1524 changed = true;
1525 }
1526 }
1527 }
1528 }
1529 }
1530
1532 changed |= BKE_layer_collection_objects_select(scene, view_layer, iter, deselect);
1533 }
1534
1535 return changed;
1536}
1537
1539 ViewLayer *view_layer,
1540 LayerCollection *lc)
1541{
1543 return false;
1544 }
1545
1546 if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
1547 BKE_view_layer_synced_ensure(scene, view_layer);
1549 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1550
1551 if (base && (base->flag & BASE_SELECTED) &&
1553 {
1554 return true;
1555 }
1556 }
1557 }
1558
1560 if (BKE_layer_collection_has_selected_objects(scene, view_layer, iter)) {
1561 return true;
1562 }
1563 }
1564
1565 return false;
1566}
1567
1569 LayerCollection *lc_child)
1570{
1571 if (lc_parent == lc_child) {
1572 return true;
1573 }
1574
1575 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
1576 if (BKE_layer_collection_has_layer_collection(lc_iter, lc_child)) {
1577 return true;
1578 }
1579 }
1580 return false;
1581}
1582
1584
1585/* -------------------------------------------------------------------- */
1588
1589void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool extend)
1590{
1591 if (!extend) {
1592 /* Make only one base visible. */
1593 BKE_view_layer_synced_ensure(scene, view_layer);
1594 LISTBASE_FOREACH (Base *, other, BKE_view_layer_object_bases_get(view_layer)) {
1595 other->flag |= BASE_HIDDEN;
1596 }
1597
1598 base->flag &= ~BASE_HIDDEN;
1599 }
1600 else {
1601 /* Toggle visibility of one base. */
1602 base->flag ^= BASE_HIDDEN;
1603 }
1604
1606}
1607
1608bool BKE_base_is_visible(const View3D *v3d, const Base *base)
1609{
1611 return false;
1612 }
1613
1614 if (v3d == nullptr) {
1616 }
1617
1618 if ((v3d->localvd) && ((v3d->local_view_uid & base->local_view_bits) == 0)) {
1619 return false;
1620 }
1621
1622 if (((1 << (base->object->type)) & v3d->object_type_exclude_viewport) != 0) {
1623 return false;
1624 }
1625
1626 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1627 return (v3d->local_collections_uid & base->local_collections_bits) != 0;
1628 }
1629
1631}
1632
1634{
1635 BLI_assert(v3d != nullptr);
1636
1638 return false;
1639 }
1640
1641 if ((v3d->object_type_exclude_viewport & (1 << ob->type)) != 0) {
1642 return false;
1643 }
1644
1645 if (v3d->localvd && ((v3d->local_view_uid & ob->base_local_view_bits) == 0)) {
1646 return false;
1647 }
1648
1649 if ((v3d->flag & V3D_LOCAL_COLLECTIONS) &&
1650 ((v3d->local_collections_uid & ob->runtime->local_collections_bits) == 0))
1651 {
1652 return false;
1653 }
1654
1655 /* If not using local collection the object may still be in a hidden collection. */
1656 if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
1658 }
1659
1660 return true;
1661}
1662
1664
1665/* -------------------------------------------------------------------- */
1668
1670{
1671 lc->flag |= flag;
1674 }
1675}
1676
1678{
1679 lc->flag &= ~flag;
1682 }
1683}
1684
1686 ViewLayer *view_layer,
1687 LayerCollection *lc,
1688 bool extend)
1689{
1690 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1691 bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER);
1692
1693 if (!extend) {
1694 /* Hide all collections. */
1695 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1697 }
1698 }
1699
1700 /* Make all the direct parents visible. */
1701 if (hide_it) {
1703 }
1704 else {
1705 LayerCollection *lc_parent = lc;
1706 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1708 lc_parent = lc_iter;
1709 break;
1710 }
1711 }
1712
1713 while (lc_parent != lc) {
1714 lc_parent->flag &= ~LAYER_COLLECTION_HIDE;
1715
1716 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
1718 lc_parent = lc_iter;
1719 break;
1720 }
1721 }
1722 }
1723
1724 /* Make all the children visible, but respect their disable state. */
1726
1727 BKE_layer_collection_activate(view_layer, lc);
1728 }
1729
1731}
1732
1734 const int local_collections_uid)
1735{
1736 layer_collection->local_collections_bits |= local_collections_uid;
1737 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1738 layer_collection_local_visibility_set_recursive(child, local_collections_uid);
1739 }
1740}
1741
1743 const int local_collections_uid)
1744{
1745 layer_collection->local_collections_bits &= ~local_collections_uid;
1746 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1747 layer_collection_local_visibility_unset_recursive(child, local_collections_uid);
1748 }
1749}
1750
1751static void layer_collection_local_sync(const Scene *scene,
1752 ViewLayer *view_layer,
1753 LayerCollection *layer_collection,
1754 const ushort local_collections_uid,
1755 bool visible)
1756{
1757 if ((layer_collection->local_collections_bits & local_collections_uid) == 0) {
1758 visible = false;
1759 }
1760
1761 if (visible) {
1762 LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) {
1763 if (cob->ob == nullptr) {
1764 continue;
1765 }
1766
1767 BKE_view_layer_synced_ensure(scene, view_layer);
1768 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1769 base->local_collections_bits |= local_collections_uid;
1770 }
1771 }
1772
1773 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1774 if ((child->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1775 layer_collection_local_sync(scene, view_layer, child, local_collections_uid, visible);
1776 }
1777 }
1778}
1779
1780void BKE_layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
1781{
1782 if (no_resync > 0) {
1783 return;
1784 }
1785
1786 const ushort local_collections_uid = v3d->local_collections_uid;
1787
1788 /* Reset flags and set the bases visible by default. */
1789 BKE_view_layer_synced_ensure(scene, view_layer);
1791 base->local_collections_bits &= ~local_collections_uid;
1792 }
1793
1794 LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
1795 layer_collection_local_sync(scene, view_layer, layer_collection, local_collections_uid, true);
1796 }
1797}
1798
1800{
1801 if (no_resync > 0) {
1802 return;
1803 }
1804
1805 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1806 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1807 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1808 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1809 if (area->spacetype != SPACE_VIEW3D) {
1810 continue;
1811 }
1812 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
1813 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1814 BKE_layer_collection_local_sync(scene, view_layer, v3d);
1815 }
1816 }
1817 }
1818 }
1819 }
1820}
1821
1823 const Scene *scene, ViewLayer *view_layer, const View3D *v3d, LayerCollection *lc, bool extend)
1824{
1825 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1826 bool hide_it = extend && ((v3d->local_collections_uid & lc->local_collections_bits) != 0);
1827
1828 if (!extend) {
1829 /* Hide all collections. */
1830 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1832 }
1833 }
1834
1835 /* Make all the direct parents visible. */
1836 if (hide_it) {
1838 }
1839 else {
1840 LayerCollection *lc_parent = lc;
1841 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1843 lc_parent = lc_iter;
1844 break;
1845 }
1846 }
1847
1848 while (lc_parent != lc) {
1850
1851 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
1853 lc_parent = lc_iter;
1854 break;
1855 }
1856 }
1857 }
1858
1859 /* Make all the children visible. */
1861 }
1862
1863 BKE_layer_collection_local_sync(scene, view_layer, v3d);
1864}
1865
1867 ViewLayer *view_layer,
1868 LayerCollection *lc)
1869{
1870 if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1871 BKE_view_layer_synced_ensure(scene, view_layer);
1873 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1874 base->flag &= ~BASE_HIDDEN;
1875 }
1876 }
1878 layer_collection_bases_show_recursive(scene, view_layer, lc_iter);
1879 }
1880}
1881
1883 ViewLayer *view_layer,
1884 LayerCollection *lc)
1885{
1886 if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1887 BKE_view_layer_synced_ensure(scene, view_layer);
1889 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1890 base->flag |= BASE_HIDDEN;
1891 }
1892 }
1894 layer_collection_bases_hide_recursive(scene, view_layer, lc_iter);
1895 }
1896}
1897
1899 ViewLayer *view_layer,
1900 LayerCollection *lc,
1901 const bool visible,
1902 const bool hierarchy)
1903{
1904 if (hierarchy) {
1905 if (visible) {
1907 layer_collection_bases_show_recursive(scene, view_layer, lc);
1908 }
1909 else {
1911 layer_collection_bases_hide_recursive(scene, view_layer, lc);
1912 }
1913 }
1914 else {
1915 if (visible) {
1917 }
1918 else {
1920 }
1921 }
1922}
1923
1929 const int flag,
1930 const bool value,
1931 const bool restore_flag)
1932{
1934 /* For exclude flag, we remember the state the children had before
1935 * excluding and restoring it when enabling the parent collection again. */
1936 if (value) {
1937 if (restore_flag) {
1940 }
1941 else {
1943 }
1944
1945 lc->flag |= flag;
1946 }
1947 else {
1949 lc->flag &= ~flag;
1950 }
1951 }
1952 }
1953 else {
1954 SET_FLAG_FROM_TEST(lc->flag, value, flag);
1955 }
1956
1958 layer_collection_flag_recursive_set(nlc, flag, value, true);
1959 }
1960}
1961
1962void BKE_layer_collection_set_flag(LayerCollection *lc, const int flag, const bool value)
1963{
1964 layer_collection_flag_recursive_set(lc, flag, value, false);
1965}
1966
1967/* ---------------------------------------------------------------------- */
1968
1970 const Collection *collection)
1971{
1972 if (lc->collection == collection) {
1973 return lc;
1974 }
1975
1978 if (found) {
1979 return found;
1980 }
1981 }
1982 return nullptr;
1983}
1984
1986 const Collection *collection)
1987{
1988 LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
1990 collection);
1991 if (found != nullptr) {
1992 return found;
1993 }
1994 }
1995 return nullptr;
1996}
1997
1998bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection *collection)
1999{
2000 return BKE_layer_collection_first_from_scene_collection(view_layer, collection) != nullptr;
2001}
2002
2004{
2005 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2006 BKE_view_layer_synced_ensure(scene, view_layer);
2007 Base *base = BKE_view_layer_base_find(view_layer, ob);
2008 if (base) {
2009 return true;
2010 }
2011 }
2012 return false;
2013}
2014
2016
2017/* Iterators */
2018
2019/* -------------------------------------------------------------------- */
2022
2027
2028static bool object_bases_iterator_is_valid(const View3D *v3d, Base *base, const int flag)
2029{
2030 BLI_assert((v3d == nullptr) || (v3d->spacetype == SPACE_VIEW3D));
2031
2032 /* Any flag satisfies the condition. */
2033 if (flag == ~0) {
2034 return (base->flag != 0);
2035 }
2036
2037 /* Flags may be more than one flag, so we can't check != 0. */
2038 return BASE_VISIBLE(v3d, base) && ((base->flag & flag) == flag);
2039}
2040
2041static void object_bases_iterator_begin(BLI_Iterator *iter, void *data_in_v, const int flag)
2042{
2043 ObjectsVisibleIteratorData *data_in = static_cast<ObjectsVisibleIteratorData *>(data_in_v);
2044 ViewLayer *view_layer = data_in->view_layer;
2045 const View3D *v3d = data_in->v3d;
2046 Base *base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
2047
2048 /* when there are no objects */
2049 if (base == nullptr) {
2050 iter->data = nullptr;
2051 iter->valid = false;
2052 return;
2053 }
2054
2056 iter->data = data;
2057
2058 data->v3d = v3d;
2059 data->base = base;
2060
2061 if (object_bases_iterator_is_valid(v3d, base, flag) == false) {
2063 }
2064 else {
2065 iter->current = base;
2066 }
2067}
2068
2069static void object_bases_iterator_next(BLI_Iterator *iter, const int flag)
2070{
2072 Base *base = data->base->next;
2073
2074 while (base) {
2075 if (object_bases_iterator_is_valid(data->v3d, base, flag)) {
2076 iter->current = base;
2077 data->base = base;
2078 return;
2079 }
2080 base = base->next;
2081 }
2082
2083 iter->valid = false;
2084}
2085
2087{
2088 MEM_SAFE_FREE(iter->data);
2089}
2090
2091static void objects_iterator_begin(BLI_Iterator *iter, void *data_in, const int flag)
2092{
2093 object_bases_iterator_begin(iter, data_in, flag);
2094
2095 if (iter->valid) {
2096 iter->current = ((Base *)iter->current)->object;
2097 }
2098}
2099
2100static void objects_iterator_next(BLI_Iterator *iter, const int flag)
2101{
2103
2104 if (iter->valid) {
2105 iter->current = ((Base *)iter->current)->object;
2106 }
2107}
2108
2110{
2112}
2113
2115
2116/* -------------------------------------------------------------------- */
2120
2126
2131
2136
2138
2139/* -------------------------------------------------------------------- */
2142
2144{
2145 objects_iterator_begin(iter, data_in, 0);
2146}
2147
2152
2157
2159
2160/* -------------------------------------------------------------------- */
2163
2165{
2168 if (iter->valid) {
2169 if (BKE_object_is_libdata((Object *)iter->current) == false) {
2170 /* First object is valid (selectable and not libdata) -> all good. */
2171 return;
2172 }
2173
2174 /* Object is selectable but not editable -> search for another one. */
2176 }
2177}
2178
2180{
2181 /* Search while there are objects and the one we have is not editable (editable = not libdata).
2182 */
2183 do {
2185 } while (iter->valid && BKE_object_is_libdata((Object *)iter->current) != false);
2186}
2187
2192
2194
2195/* -------------------------------------------------------------------- */
2198
2204
2209
2214
2216
2217/* -------------------------------------------------------------------- */
2220
2222{
2223 object_bases_iterator_begin(iter, data_in, 0);
2224}
2225
2230
2235
2237
2238/* -------------------------------------------------------------------- */
2241
2243{
2244 return (base->object->type == data->object_type) &&
2245 (base->object->mode & data->object_mode) != 0;
2246}
2247
2249{
2250 ObjectsInModeIteratorData *data = static_cast<ObjectsInModeIteratorData *>(data_in);
2251 Base *base = data->base_active;
2252
2253 /* In this case the result will always be empty, the caller must check for no mode. */
2254 BLI_assert(data->object_mode != 0);
2255
2256 /* when there are no objects */
2257 if (base == nullptr) {
2258 iter->valid = false;
2259 return;
2260 }
2261 iter->data = data_in;
2262 iter->current = base;
2263
2264 /* default type is active object type */
2265 if (data->object_type < 0) {
2266 data->object_type = base->object->type;
2267 }
2268
2269 if (!(base_is_in_mode(data, base) && BKE_base_is_visible(data->v3d, base))) {
2271 }
2272}
2273
2275{
2277 Base *base = static_cast<Base *>(iter->current);
2278
2279 if (base == data->base_active) {
2280 /* first step */
2281 base = static_cast<Base *>(data->view_layer->object_bases.first);
2282 if ((base == data->base_active) && BKE_base_is_visible(data->v3d, base)) {
2283 base = base->next;
2284 }
2285 }
2286 else {
2287 base = base->next;
2288 }
2289
2290 while (base) {
2291 if ((base != data->base_active) && base_is_in_mode(data, base) &&
2292 BKE_base_is_visible(data->v3d, base))
2293 {
2294 iter->current = base;
2295 return;
2296 }
2297 base = base->next;
2298 }
2299 iter->valid = false;
2300}
2301
2303{
2304 /* do nothing */
2305}
2306
2308
2309/* -------------------------------------------------------------------- */
2312
2314{
2315 /* Apply collection flags. */
2318
2319 /* Apply object restrictions. */
2320 const int object_restrict = base->object->visibility_flag;
2321 if (object_restrict & OB_HIDE_VIEWPORT) {
2323 }
2324 if (object_restrict & OB_HIDE_RENDER) {
2325 base->flag &= ~BASE_ENABLED_RENDER;
2326 }
2327 if (object_restrict & OB_HIDE_SELECT) {
2328 base->flag &= ~BASE_SELECTABLE;
2329 }
2330
2331 /* Apply viewport visibility by default. The dependency graph for render
2332 * can change these again, but for tools we always want the viewport
2333 * visibility to be in sync regardless if depsgraph was evaluated. */
2334 if (!(base->flag & BASE_ENABLED_VIEWPORT) || (base->flag & BASE_HIDDEN)) {
2337 }
2338
2339 /* Deselect unselectable objects. */
2340 if (!(base->flag & BASE_SELECTABLE)) {
2341 base->flag &= ~BASE_SELECTED;
2342 }
2343}
2344
2345static void layer_eval_view_layer(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer)
2346{
2347 DEG_debug_print_eval(depsgraph, __func__, view_layer->name, view_layer);
2348
2349 /* Create array of bases, for fast index-based lookup. */
2350 BKE_view_layer_synced_ensure(scene, view_layer);
2351 const int num_object_bases = BLI_listbase_count(BKE_view_layer_object_bases_get(view_layer));
2352 MEM_SAFE_FREE(view_layer->object_bases_array);
2353 view_layer->object_bases_array = MEM_malloc_arrayN<Base *>(size_t(num_object_bases),
2354 "view_layer->object_bases_array");
2355 int base_index = 0;
2357 view_layer->object_bases_array[base_index++] = base;
2358 }
2359}
2360
2361void BKE_layer_eval_view_layer_indexed(Depsgraph *depsgraph, Scene *scene, int view_layer_index)
2362{
2363 BLI_assert(view_layer_index >= 0);
2364 ViewLayer *view_layer = static_cast<ViewLayer *>(
2365 BLI_findlink(&scene->view_layers, view_layer_index));
2366 BLI_assert(view_layer != nullptr);
2367 layer_eval_view_layer(depsgraph, scene, view_layer);
2368}
2369
2371
2372/* -------------------------------------------------------------------- */
2375
2377{
2378 LISTBASE_FOREACH (LayerCollection *, lc, lb) {
2379 BLO_write_struct(writer, LayerCollection, lc);
2380
2381 write_layer_collections(writer, &lc->layer_collections);
2382 }
2383}
2384
2385void BKE_view_layer_blend_write(BlendWriter *writer, const Scene *scene, ViewLayer *view_layer)
2386{
2387 BKE_view_layer_synced_ensure(scene, view_layer);
2388 BLO_write_struct(writer, ViewLayer, view_layer);
2390
2391 if (view_layer->id_properties) {
2392 IDP_BlendWrite(writer, view_layer->id_properties);
2393 }
2394 if (view_layer->system_properties) {
2395 IDP_BlendWrite(writer, view_layer->system_properties);
2396 }
2397
2400 }
2401
2403 BLO_write_struct(writer, FreestyleLineSet, fls);
2404 }
2405 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2406 BLO_write_struct(writer, ViewLayerAOV, aov);
2407 }
2408 LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
2409 BLO_write_struct(writer, ViewLayerLightgroup, lightgroup);
2410 }
2411 write_layer_collections(writer, &view_layer->layer_collections);
2412}
2413
2415 ViewLayer *view_layer,
2416 ListBase *lb,
2417 bool master,
2418 bool &active_collection_found)
2419{
2421 LISTBASE_FOREACH (LayerCollection *, lc, lb) {
2422 /* Master collection is not a real data-block. */
2423 if (master) {
2424 BLO_read_struct(reader, Collection, &lc->collection);
2425 }
2426
2427 if (lc == view_layer->active_collection) {
2428 active_collection_found = true;
2429 }
2430
2432 reader, view_layer, &lc->layer_collections, false, active_collection_found);
2433 }
2434}
2435
2437{
2438 view_layer->stats = nullptr;
2439 BLO_read_struct_list(reader, Base, &view_layer->object_bases);
2440 BLO_read_struct(reader, Base, &view_layer->basact);
2441
2442 bool active_collection_found = false;
2443 BLO_read_struct(reader, LayerCollection, &view_layer->active_collection);
2444
2446 reader, view_layer, &view_layer->layer_collections, true, active_collection_found);
2447
2448 if (!active_collection_found) {
2449 /* Ensure pointer is valid, in case of corrupt blend file. */
2450 view_layer->active_collection = static_cast<LayerCollection *>(
2451 view_layer->layer_collections.first);
2452 }
2453
2454 BLO_read_struct(reader, IDProperty, &view_layer->id_properties);
2455 IDP_BlendDataRead(reader, &view_layer->id_properties);
2456 BLO_read_struct(reader, IDProperty, &view_layer->system_properties);
2457 IDP_BlendDataRead(reader, &view_layer->system_properties);
2458
2461
2462 BLO_read_struct_list(reader, ViewLayerAOV, &view_layer->aovs);
2463 BLO_read_struct(reader, ViewLayerAOV, &view_layer->active_aov);
2464
2467
2468 view_layer->object_bases_array = nullptr;
2469 view_layer->object_bases_hash = nullptr;
2470}
2471
2473 ID * /*self_id*/,
2474 ViewLayer *view_layer)
2475{
2476 LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
2477 if (base->object == nullptr) {
2478 /* Free in case linked object got lost. */
2479 BLI_freelinkN(&view_layer->object_bases, base);
2480 if (view_layer->basact == base) {
2481 view_layer->basact = nullptr;
2482 }
2483 }
2484 }
2485}
2486
2488
2489/* -------------------------------------------------------------------- */
2492
2494{
2495 ViewLayerAOV *aov = view_layer->active_aov;
2496 if (aov == nullptr) {
2497 return;
2498 }
2499
2500 /* Don't allow dots, it's incompatible with OpenEXR convention to store channels
2501 * as "layer.pass.channel". */
2502 BLI_string_replace_char(aov->name, '.', '_');
2504 &view_layer->aovs, aov, DATA_("AOV"), '_', offsetof(ViewLayerAOV, name), sizeof(aov->name));
2505}
2506
2508{
2509 if (aov != nullptr) {
2510 BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1);
2511 view_layer->active_aov = aov;
2512 }
2513 else {
2514 view_layer->active_aov = nullptr;
2515 }
2516}
2517
2519{
2520 ViewLayerAOV *aov;
2521 aov = MEM_callocN<ViewLayerAOV>(__func__);
2522 aov->type = AOV_TYPE_COLOR;
2523 STRNCPY_UTF8(aov->name, DATA_("AOV"));
2524 BLI_addtail(&view_layer->aovs, aov);
2525 viewlayer_aov_active_set(view_layer, aov);
2527 return aov;
2528}
2529
2531{
2532 BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1);
2533 BLI_assert(aov != nullptr);
2534 if (view_layer->active_aov == aov) {
2535 if (aov->next) {
2536 viewlayer_aov_active_set(view_layer, aov->next);
2537 }
2538 else {
2539 viewlayer_aov_active_set(view_layer, aov->prev);
2540 }
2541 }
2542 BLI_freelinkN(&view_layer->aovs, aov);
2543}
2544
2546{
2547 viewlayer_aov_active_set(view_layer, aov);
2548}
2549
2550static void bke_view_layer_verify_aov_cb(void *userdata,
2551 Scene * /*scene*/,
2552 ViewLayer * /*view_layer*/,
2553 const char *name,
2554 int /*channels*/,
2555 const char * /*chanid*/,
2556 eNodeSocketDatatype /*type*/)
2557{
2558 GHash *name_count = static_cast<GHash *>(userdata);
2559 void **value_p;
2560 void *key = BLI_strdup(name);
2561
2562 if (!BLI_ghash_ensure_p(name_count, key, &value_p)) {
2563 *value_p = POINTER_FROM_INT(1);
2564 }
2565 else {
2566 int value = POINTER_AS_INT(*value_p);
2567 value++;
2568 *value_p = POINTER_FROM_INT(value);
2569 MEM_freeN(key);
2570 }
2571}
2572
2573void BKE_view_layer_verify_aov(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
2574{
2576
2577 GHash *name_count = BLI_ghash_str_new(__func__);
2578 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2579 /* Disable conflict flag, so that the AOV is included when iterating over all passes below. */
2580 aov->flag &= ~AOV_CONFLICT;
2581 }
2583 engine, scene, view_layer, bke_view_layer_verify_aov_cb, name_count);
2584 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2585 void **value_p = static_cast<void **>(BLI_ghash_lookup(name_count, aov->name));
2586 int count = POINTER_AS_INT(value_p);
2587 SET_FLAG_FROM_TEST(aov->flag, count > 1, AOV_CONFLICT);
2588 }
2589 BLI_ghash_free(name_count, MEM_freeN, nullptr);
2590}
2591
2593{
2594 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2595 if ((aov->flag & AOV_CONFLICT) == 0) {
2596 return true;
2597 }
2598 }
2599 return false;
2600}
2601
2603{
2604 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2605 if (BLI_findindex(&view_layer->aovs, aov) != -1) {
2606 return view_layer;
2607 }
2608 }
2609 return nullptr;
2610}
2611
2613
2614/* -------------------------------------------------------------------- */
2617
2619 ViewLayerLightgroup *lightgroup)
2620{
2621 /* Don't allow dots, it's incompatible with OpenEXR convention to store channels
2622 * as "layer.pass.channel". */
2623 BLI_string_replace_char(lightgroup->name, '.', '_');
2624 BLI_uniquename(&view_layer->lightgroups,
2625 lightgroup,
2626 DATA_("Lightgroup"),
2627 '_',
2629 sizeof(lightgroup->name));
2630}
2631
2633{
2634 if (lightgroup != nullptr) {
2635 BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1);
2636 view_layer->active_lightgroup = lightgroup;
2637 }
2638 else {
2639 view_layer->active_lightgroup = nullptr;
2640 }
2641}
2642
2644{
2645 ViewLayerLightgroup *lightgroup;
2646 lightgroup = MEM_callocN<ViewLayerLightgroup>(__func__);
2647 STRNCPY_UTF8(lightgroup->name, (name && name[0]) ? name : DATA_("Lightgroup"));
2648 BLI_addtail(&view_layer->lightgroups, lightgroup);
2649 viewlayer_lightgroup_active_set(view_layer, lightgroup);
2650 viewlayer_lightgroup_make_name_unique(view_layer, lightgroup);
2651 return lightgroup;
2652}
2653
2655{
2656 BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1);
2657 BLI_assert(lightgroup != nullptr);
2658 if (view_layer->active_lightgroup == lightgroup) {
2659 if (lightgroup->next) {
2660 viewlayer_lightgroup_active_set(view_layer, lightgroup->next);
2661 }
2662 else {
2663 viewlayer_lightgroup_active_set(view_layer, lightgroup->prev);
2664 }
2665 }
2666 BLI_freelinkN(&view_layer->lightgroups, lightgroup);
2667}
2668
2670{
2671 viewlayer_lightgroup_active_set(view_layer, lightgroup);
2672}
2673
2675{
2676 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2677 if (BLI_findindex(&view_layer->lightgroups, lightgroup) != -1) {
2678 return view_layer;
2679 }
2680 }
2681 return nullptr;
2682}
2683
2685 ViewLayer *view_layer,
2686 ViewLayerLightgroup *lightgroup,
2687 const char *name)
2688{
2689 char old_name[64];
2690 STRNCPY_UTF8(old_name, lightgroup->name);
2691 STRNCPY_UTF8(lightgroup->name, name);
2692 viewlayer_lightgroup_make_name_unique(view_layer, lightgroup);
2693
2694 if (scene != nullptr) {
2695 /* Update objects in the scene to refer to the new name instead. */
2696 FOREACH_SCENE_OBJECT_BEGIN (scene, ob) {
2697 if (ID_IS_EDITABLE(ob) && ob->lightgroup != nullptr) {
2698 LightgroupMembership *lgm = ob->lightgroup;
2699 if (STREQ(lgm->name, old_name)) {
2700 STRNCPY_UTF8(lgm->name, lightgroup->name);
2701 }
2702 }
2703 }
2705
2706 /* Update the scene's world to refer to the new name instead. */
2707 if (scene->world != nullptr && ID_IS_EDITABLE(scene->world) &&
2708 scene->world->lightgroup != nullptr)
2709 {
2710 LightgroupMembership *lgm = scene->world->lightgroup;
2711 if (STREQ(lgm->name, old_name)) {
2712 STRNCPY_UTF8(lgm->name, lightgroup->name);
2713 }
2714 }
2715 }
2716}
2717
2719{
2720 if (lgm == nullptr) {
2721 name[0] = '\0';
2722 return 0;
2723 }
2724 return BLI_strncpy_utf8_rlen(name, lgm->name, sizeof(lgm->name));
2725}
2726
2728{
2729 if (lgm == nullptr) {
2730 return 0;
2731 }
2732 return strlen(lgm->name);
2733}
2734
2736{
2737 if (name[0] != '\0') {
2738 if (*lgm == nullptr) {
2739 *lgm = MEM_callocN<LightgroupMembership>(__func__);
2740 }
2741 BLI_strncpy_utf8((*lgm)->name, name, sizeof((*lgm)->name));
2742 }
2743 else {
2744 if (*lgm != nullptr) {
2745 MEM_freeN(*lgm);
2746 *lgm = nullptr;
2747 }
2748 }
2749}
2750
void BKE_animdata_fix_paths_rename_all(struct ID *ref_id, const char *prefix, const char *oldName, const char *newName)
#define FOREACH_SCENE_OBJECT_END
void BKE_main_collections_object_cache_free(const Main *bmain)
#define FOREACH_SCENE_OBJECT_BEGIN(scene, _instance)
void BKE_freestyle_config_copy(struct FreestyleConfig *new_config, const struct FreestyleConfig *config, int flag)
void BKE_freestyle_config_init(struct FreestyleConfig *config)
Definition freestyle.cc:31
void BKE_freestyle_config_free(struct FreestyleConfig *config, bool do_id_user)
Definition freestyle.cc:44
#define IDP_BlendDataRead(reader, prop)
IDProperty * IDP_CopyProperty_ex(const IDProperty *prop, int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition idprop.cc:845
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
Definition idprop.cc:1461
void IDP_FreeProperty_ex(IDProperty *prop, bool do_id_user)
Definition idprop.cc:1245
@ VIEWLAYER_ADD_NEW
Definition BKE_layer.hh:34
@ VIEWLAYER_ADD_EMPTY
Definition BKE_layer.hh:35
@ VIEWLAYER_ADD_COPY
Definition BKE_layer.hh:36
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void id_us_plus(ID *id)
Definition lib_id.cc:358
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void id_lib_indirect_weak_link(ID *id)
Definition lib_id.cc:303
#define CMP_NODE_R_LAYERS
General operations, lookup, etc. for blender objects.
bool BKE_object_is_libdata(const Object *ob)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
unsigned int BLI_ghashutil_ptrhash(const void *key)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:686
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.cc:787
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:731
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.cc:860
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:752
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:270
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
int BLI_listbase_count_at_most(const ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:511
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:131
void * BLI_findptr(const struct ListBase *listbase, const void *ptr, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
void void BLI_INLINE bool BLI_listbase_is_single(const ListBase *lb)
@ BLI_MEMPOOL_NOP
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
char * BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
char size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
void BLI_string_replace_char(char *str, char src, char dst) ATTR_NONNULL(1)
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
unsigned short ushort
#define POINTER_FROM_INT(i)
#define UNUSED_VARS_NDEBUG(...)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define POINTER_AS_INT(i)
#define ELEM(...)
#define STREQ(a, b)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define DATA_(msgid)
#define CLOG_DEBUG(clg_ref,...)
Definition CLG_log.h:191
#define CLOG_FATAL(clg_ref,...)
Definition CLG_log.h:187
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_debug_print_eval(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
ID and Library types, which are fundamental for SDNA.
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1104
#define ID_IS_LINKED(_id)
Definition DNA_ID.h:694
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_RENDER
@ COLLECTION_HIDE_SELECT
@ COLLECTION_IS_MASTER
@ COLLECTION_HIDE_VIEWPORT
#define DNA_struct_default_get(struct_name)
@ LAYER_COLLECTION_HIDE
@ LAYER_COLLECTION_EXCLUDE
@ LAYER_COLLECTION_INDIRECT_ONLY
@ LAYER_COLLECTION_PREVIOUSLY_EXCLUDED
@ LAYER_COLLECTION_HOLDOUT
@ BASE_HIDDEN
@ BASE_INDIRECT_ONLY
@ BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT
@ BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT
@ BASE_ENABLED_RENDER
@ BASE_HOLDOUT
@ BASE_ENABLED_VIEWPORT
@ LAYER_COLLECTION_VISIBLE_VIEW_LAYER
@ LAYER_COLLECTION_HIDE_VIEWPORT
@ LAYER_COLLECTION_HAS_OBJECTS
@ AOV_TYPE_COLOR
@ AOV_CONFLICT
@ VIEW_LAYER_HAS_EXPORT_COLLECTIONS
@ VIEW_LAYER_RENDER
@ VIEW_LAYER_OUT_OF_SYNC
eNodeSocketDatatype
Object is a sort of wrapper for general info.
@ OB_HIDE_RENDER
@ OB_HIDE_SELECT
@ OB_HIDE_VIEWPORT
@ OB_CAMERA
#define BASE_SELECTED(v3d, base)
#define BASE_SELECTABLE(v3d, base)
#define BASE_VISIBLE(v3d, base)
@ SPACE_VIEW3D
@ V3D_LOCAL_COLLECTIONS
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
volatile int lock
void BKE_view_layer_bases_in_mode_iterator_begin(BLI_Iterator *iter, void *data_in)
void BKE_view_layer_bases_in_mode_iterator_next(BLI_Iterator *iter)
void BKE_view_layer_blend_write(BlendWriter *writer, const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_rename_lightgroup(Scene *scene, ViewLayer *view_layer, ViewLayerLightgroup *lightgroup, const char *name)
LayerCollection * BKE_layer_collection_first_from_scene_collection(const ViewLayer *view_layer, const Collection *collection)
static void layer_aov_copy_data(ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, ListBase *aovs_dst, const ListBase *aovs_src)
ViewLayerLightgroup * BKE_view_layer_add_lightgroup(ViewLayer *view_layer, const char *name)
bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection *collection)
void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_layer)
ViewLayer * BKE_view_layer_find_with_aov(Scene *scene, ViewLayerAOV *aov)
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
void BKE_view_layer_set_active_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc)
static LayerCollection * collection_from_index(ListBase *lb, const int number, int *i)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
static void layer_collection_flag_set_recursive(LayerCollection *lc, const int flag)
bool BKE_view_layer_has_valid_aov(ViewLayer *view_layer)
static void object_bases_iterator_end(BLI_Iterator *iter)
void BKE_layer_collection_resync_forbid()
void BKE_view_layer_visible_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
static void layer_collection_exclude_all(LayerCollection *layer_collection)
void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
void BKE_scene_view_layers_synced_ensure(const Scene *scene)
void BKE_main_collection_sync_remap(const Main *bmain)
static void object_bases_iterator_begin(BLI_Iterator *iter, void *data_in_v, const int flag)
static void viewlayer_lightgroup_active_set(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
void BKE_view_layer_selected_editable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
static void layer_collection_local_visibility_set_recursive(LayerCollection *layer_collection, const int local_collections_uid)
static int index_from_collection(ListBase *lb, const LayerCollection *lc, int *i)
void BKE_view_layer_set_active_aov(ViewLayer *view_layer, ViewLayerAOV *aov)
static void viewlayer_lightgroup_make_name_unique(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
void BKE_view_layer_remove_aov(ViewLayer *view_layer, ViewLayerAOV *aov)
void BKE_view_layer_remove_lightgroup(ViewLayer *view_layer, ViewLayerLightgroup *lightgroup)
void BKE_layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
static LayerCollectionResync * layer_collection_resync_create_recurse(LayerCollectionResync *parent_layer_resync, LayerCollection *layer, BLI_mempool *mempool)
void BKE_view_layer_selected_editable_objects_iterator_end(BLI_Iterator *iter)
bool BKE_layer_collection_objects_select(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool deselect)
void BKE_view_layer_selected_objects_tag(const Scene *scene, ViewLayer *view_layer, const int tag)
static void viewlayer_aov_active_set(ViewLayer *view_layer, ViewLayerAOV *aov)
void BKE_view_layer_selected_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
static void layer_collection_flag_recursive_set(LayerCollection *lc, const int flag, const bool value, const bool restore_flag)
static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter)
void BKE_view_layer_free_object_content(ViewLayer *view_layer)
static void layer_lightgroup_copy_data(ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, ListBase *lightgroups_dst, const ListBase *lightgroups_src)
void BKE_layer_collection_isolate_local(const Scene *scene, ViewLayer *view_layer, const View3D *v3d, LayerCollection *lc, bool extend)
static void layer_collection_bases_hide_recursive(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc)
void BKE_view_layer_selected_objects_iterator_end(BLI_Iterator *iter)
void BKE_layer_collection_set_flag(LayerCollection *lc, const int flag, const bool value)
void BKE_view_layer_selected_editable_objects_iterator_next(BLI_Iterator *iter)
static void layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, LayerCollection *layer_collection, const ushort local_collections_uid, bool visible)
bool BKE_layer_collection_has_selected_objects(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc)
static void layer_collection_objects_sync(ViewLayer *view_layer, LayerCollection *layer, ListBase *r_lb_new_object_bases, const short collection_restrict, const short layer_restrict, const ushort local_collections_bits)
void BKE_layer_collection_resync_allow()
static int collection_count(const ListBase *lb)
void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
void BKE_view_layer_verify_aov(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
void BKE_layer_eval_view_layer_indexed(Depsgraph *depsgraph, Scene *scene, int view_layer_index)
Object * BKE_view_layer_camera_find(const Scene *scene, ViewLayer *view_layer)
static const short g_base_collection_flags
static std::atomic< int32_t > no_resync
ViewLayer * BKE_view_layer_find_with_lightgroup(Scene *scene, ViewLayerLightgroup *lightgroup)
static LayerCollection * layer_collection_add(ListBase *lb_parent, Collection *collection)
int BKE_lightgroup_membership_length(const LightgroupMembership *lgm)
static bool base_is_in_mode(ObjectsInModeIteratorData *data, Base *base)
ViewLayer * BKE_view_layer_default_view(const Scene *scene)
static ViewLayer * view_layer_add(const char *name)
void BKE_view_layer_selected_bases_iterator_next(BLI_Iterator *iter)
static void write_layer_collections(BlendWriter *writer, ListBase *lb)
ViewLayer * BKE_view_layer_find(const Scene *scene, const char *layer_name)
void BKE_layer_collection_isolate_global(Scene *, ViewLayer *view_layer, LayerCollection *lc, bool extend)
static void layer_collection_sync(ViewLayer *view_layer, LayerCollectionResync *layer_resync, BLI_mempool *layer_resync_mempool, ListBase *r_lb_new_object_bases, const short parent_layer_flag, const short parent_collection_restrict, const short parent_layer_restrict, const ushort parent_local_collections_bits)
static void layer_collection_local_visibility_unset_recursive(LayerCollection *layer_collection, const int local_collections_uid)
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
void BKE_scene_collection_sync(const Scene *scene)
bool BKE_object_is_visible_in_viewport(const View3D *v3d, const Object *ob)
void BKE_view_layer_visible_objects_iterator_end(BLI_Iterator *iter)
ViewLayer * BKE_view_layer_context_active_PLACEHOLDER(const Scene *scene)
void BKE_view_layer_selected_bases_iterator_end(BLI_Iterator *iter)
void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, const char *newname)
void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool extend)
static void objects_iterator_next(BLI_Iterator *iter, const int flag)
int BKE_layer_collection_count(const ViewLayer *view_layer)
static void layer_collection_flag_unset_recursive(LayerCollection *lc, const int flag)
bool BKE_layer_collection_has_layer_collection(LayerCollection *lc_parent, LayerCollection *lc_child)
void BKE_view_layer_need_resync_tag(ViewLayer *view_layer)
static void objects_iterator_end(BLI_Iterator *iter)
bool BKE_scene_has_object(Scene *scene, Object *ob)
static LayerCollectionResync * layer_collection_resync_find(LayerCollectionResync *layer_resync, Collection *child_collection)
void BKE_main_collection_sync(const Main *bmain)
void BKE_view_layer_free(ViewLayer *view_layer)
static void layer_collection_resync_unused_layers_free(ViewLayer *view_layer, LayerCollectionResync *layer_resync)
static void viewlayer_aov_make_name_unique(ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
void BKE_layer_collection_doversion_2_80(const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_visible_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
ViewLayer * BKE_view_layer_add(Scene *scene, const char *name, ViewLayer *view_layer_source, const int type)
static bool object_bases_iterator_is_valid(const View3D *v3d, Base *base, const int flag)
static void direct_link_layer_collections(BlendDataReader *reader, ViewLayer *view_layer, ListBase *lb, bool master, bool &active_collection_found)
LayerCollection * BKE_layer_collection_from_index(ViewLayer *view_layer, const int index)
static Base * object_base_new(Object *ob)
LayerCollection * BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc)
static void layer_collections_copy_data(ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, ListBase *layer_collections_dst, const ListBase *layer_collections_src)
void BKE_view_layer_selected_bases_iterator_begin(BLI_Iterator *iter, void *data_in)
static constexpr int no_resync_recurse_max
void BKE_lightgroup_membership_set(LightgroupMembership **lgm, const char *name)
static void layer_eval_view_layer(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer)
static void object_bases_iterator_next(BLI_Iterator *iter, const int flag)
int BKE_lightgroup_membership_get(const LightgroupMembership *lgm, char *name)
static void objects_iterator_begin(BLI_Iterator *iter, void *data_in, const int flag)
void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
static bool view_layer_objects_base_cache_validate(ViewLayer *view_layer, LayerCollection *layer)
static void view_layer_bases_hash_create(ViewLayer *view_layer, const bool do_base_duplicates_fix)
int BKE_layer_collection_findindex(ViewLayer *view_layer, const LayerCollection *lc)
bool BKE_layer_collection_activate(ViewLayer *view_layer, LayerCollection *lc)
ViewLayerAOV * BKE_view_layer_add_aov(ViewLayer *view_layer)
void BKE_base_eval_flags(Base *base)
ViewLayer * BKE_view_layer_default_render(const Scene *scene)
void BKE_main_view_layers_synced_ensure(const Main *bmain)
static void layer_collection_bases_show_recursive(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc)
void BKE_view_layer_visible_bases_iterator_next(BLI_Iterator *iter)
void BKE_view_layer_base_select_and_set_active(ViewLayer *view_layer, Base *selbase)
static LayerCollection * find_layer_collection_by_scene_collection(LayerCollection *lc, const Collection *collection)
void BKE_layer_collection_local_sync_all(const Main *bmain)
void BKE_view_layer_blend_read_after_liblink(BlendLibReader *, ID *, ViewLayer *view_layer)
void BKE_view_layer_copy_data(Scene *scene_dst, const Scene *, ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, const int flag)
ViewLayer * BKE_view_layer_find_from_collection(const Scene *scene, LayerCollection *lc)
void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *)
void BKE_layer_collection_set_visible(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc, const bool visible, const bool hierarchy)
void BKE_view_layer_visible_objects_iterator_next(BLI_Iterator *iter)
void BKE_view_layer_selected_objects_iterator_next(BLI_Iterator *iter)
static void bke_view_layer_verify_aov_cb(void *userdata, Scene *, ViewLayer *, const char *name, int, const char *, eNodeSocketDatatype)
BMesh const char void * data
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
#define offsetof(t, d)
#define active
int count
void RE_engine_update_render_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer, update_render_passes_cb_t callback, void *callback_data)
DEG_id_tag_update_ex(cb_data->bmain, cb_data->owner_id, ID_RECALC_TAG_FOR_UNDO|ID_RECALC_SYNC_TO_EVAL)
#define LOG(level)
Definition log.h:97
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void * MEM_dupallocN(const void *vmemh)
Definition mallocn.cc:143
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
std::mutex Mutex
Definition BLI_mutex.hh:47
#define hash
Definition noise_c.cc:154
const char * name
short flag_from_collection
struct Base * next
short flag
struct Object * object
unsigned short local_view_bits
unsigned short local_collections_bits
struct Collection * collection
CollectionRuntimeHandle * runtime
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
LayerCollectionResync * parent_layer_resync
LayerCollectionResync * queue_next
LayerCollectionResync * next
LayerCollectionResync * prev
struct LayerCollection * next
ListBase layer_collections
unsigned short local_collections_bits
struct Collection * collection
void * last
void * first
ListBase scenes
Definition BKE_main.hh:278
ListBase wm
Definition BKE_main.hh:307
ListBase screens
Definition BKE_main.hh:292
ListBase collections
Definition BKE_main.hh:298
short base_flag
ObjectRuntimeHandle * runtime
short visibility_flag
unsigned short base_local_view_bits
struct Collection * master_collection
struct bNodeTree * compositing_node_group
ListBase view_layers
struct World * world
unsigned short local_collections_uid
struct View3D * localvd
int object_type_exclude_viewport
unsigned short local_view_uid
struct ViewLayerAOV * prev
struct ViewLayerAOV * next
struct ViewLayerLightgroup * prev
struct ViewLayerLightgroup * next
struct FreestyleConfig freestyle_config
ListBase lightgroups
struct IDProperty * id_properties
ViewLayerLightgroup * active_lightgroup
ViewLayerAOV * active_aov
ListBase layer_collections
LayerCollection * active_collection
struct GHash * object_bases_hash
struct Base ** object_bases_array
struct Base * basact
struct SceneStats * stats
struct IDProperty * system_properties
ListBase object_bases
ListBase aovs
struct Material * mat_override
char name[64]
struct LightgroupMembership * lightgroup
i
Definition text_draw.cc:230
uint8_t flag
Definition wm_window.cc:145