Blender V4.5
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_layer_types.h"
41#include "DNA_node_types.h"
42#include "DNA_object_types.h"
43#include "DNA_scene_types.h"
44#include "DNA_space_types.h"
45#include "DNA_view3d_types.h"
47#include "DNA_world_types.h"
48
49#include "DEG_depsgraph.hh"
52
53#include "DRW_engine.hh"
54
55#include "RE_engine.h"
56
57#include "MEM_guardedalloc.h"
58
59#include "BLO_read_write.hh"
60
61static CLG_LogRef LOG = {"bke.layercollection"};
62
63/* Set of flags which are dependent on a collection settings. */
69
70/* prototype */
71static void object_bases_iterator_next(BLI_Iterator *iter, const int flag);
72
73/* -------------------------------------------------------------------- */
76
78{
79 LayerCollection *lc = MEM_callocN<LayerCollection>("Collection Base");
80 lc->collection = collection;
82 BLI_addtail(lb_parent, lc);
83
84 return lc;
85}
86
87static void layer_collection_free(ViewLayer *view_layer, LayerCollection *lc)
88{
89 if (lc == view_layer->active_collection) {
90 view_layer->active_collection = nullptr;
91 }
92
94 layer_collection_free(view_layer, nlc);
95 MEM_freeN(nlc);
96 }
98}
99
101{
102 Base *base = MEM_callocN<Base>("Object Base");
103 base->object = ob;
104 base->local_view_bits = ~0;
105 if (ob->base_flag & BASE_SELECTED) {
106 base->flag |= BASE_SELECTED;
107 }
108 return base;
109}
110
112
113/* -------------------------------------------------------------------- */
116
117/* RenderLayer */
118
120{
121 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
122 if (!(view_layer->flag & VIEW_LAYER_RENDER)) {
123 return view_layer;
124 }
125 }
126
128 return static_cast<ViewLayer *>(scene->view_layers.first);
129}
130
132{
133 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
134 if (view_layer->flag & VIEW_LAYER_RENDER) {
135 return view_layer;
136 }
137 }
138
140 return static_cast<ViewLayer *>(scene->view_layers.first);
141}
142
143ViewLayer *BKE_view_layer_find(const Scene *scene, const char *layer_name)
144{
145 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
146 if (STREQ(view_layer->name, layer_name)) {
147 return view_layer;
148 }
149 }
150
151 return nullptr;
152}
153
155{
157 return static_cast<ViewLayer *>(scene->view_layers.first);
158}
159
160static ViewLayer *view_layer_add(const char *name)
161{
162 if (!name) {
163 name = DATA_("ViewLayer");
164 }
165
166 ViewLayer *view_layer = MEM_callocN<ViewLayer>("View Layer");
168
169 STRNCPY_UTF8(view_layer->name, name);
170
171 /* Pure rendering pipeline settings. */
172 view_layer->layflag = SCE_LAY_FLAG_DEFAULT;
173 view_layer->passflag = SCE_PASS_COMBINED;
174 view_layer->pass_alpha_threshold = 0.5f;
175 view_layer->cryptomatte_levels = 6;
178
179 return view_layer;
180}
181
182static void layer_collection_exclude_all(LayerCollection *layer_collection)
183{
184 LayerCollection *sub_collection = static_cast<LayerCollection *>(
185 layer_collection->layer_collections.first);
186 for (; sub_collection != nullptr; sub_collection = sub_collection->next) {
187 sub_collection->flag |= LAYER_COLLECTION_EXCLUDE;
188 layer_collection_exclude_all(sub_collection);
189 }
190}
191
193 const char *name,
194 ViewLayer *view_layer_source,
195 const int type)
196{
197 ViewLayer *view_layer_new;
198
199 if (view_layer_source) {
200 name = view_layer_source->name;
201 }
202
203 switch (type) {
204 default:
205 case VIEWLAYER_ADD_NEW: {
206 view_layer_new = view_layer_add(name);
207 BLI_addtail(&scene->view_layers, view_layer_new);
208 BKE_layer_collection_sync(scene, view_layer_new);
209 break;
210 }
211 case VIEWLAYER_ADD_COPY: {
212 /* Allocate and copy view layer data */
213 view_layer_new = MEM_callocN<ViewLayer>("View Layer");
214 *view_layer_new = *view_layer_source;
215 BKE_view_layer_copy_data(scene, scene, view_layer_new, view_layer_source, 0);
216 BLI_addtail(&scene->view_layers, view_layer_new);
217
218 STRNCPY_UTF8(view_layer_new->name, name);
219 break;
220 }
221 case VIEWLAYER_ADD_EMPTY: {
222 view_layer_new = view_layer_add(name);
223 BLI_addtail(&scene->view_layers, view_layer_new);
224
225 /* Initialize layer-collections. */
226 BKE_layer_collection_sync(scene, view_layer_new);
228 static_cast<LayerCollection *>(view_layer_new->layer_collections.first));
229
230 /* Update collections after changing visibility */
231 BKE_layer_collection_sync(scene, view_layer_new);
232 break;
233 }
234 }
235
236 /* unique name */
238 view_layer_new,
239 DATA_("ViewLayer"),
240 '_',
241 offsetof(ViewLayer, name),
242 sizeof(view_layer_new->name));
243
244 return view_layer_new;
245}
246
248{
249 BKE_view_layer_free_ex(view_layer, true);
250}
251
252void BKE_view_layer_free_ex(ViewLayer *view_layer, const bool do_id_user)
253{
255
256 BLI_freelistN(&view_layer->aovs);
257 view_layer->active_aov = nullptr;
258 BLI_freelistN(&view_layer->lightgroups);
259 view_layer->active_lightgroup = nullptr;
260
261 /* Cannot use MEM_SAFE_FREE, as #SceneStats type is only forward-declared in `DNA_layer_types.h`
262 */
263 if (view_layer->stats) {
264 MEM_freeN(static_cast<void *>(view_layer->stats));
265 view_layer->stats = nullptr;
266 }
267
268 BKE_freestyle_config_free(&view_layer->freestyle_config, do_id_user);
269
270 if (view_layer->id_properties) {
271 IDP_FreeProperty_ex(view_layer->id_properties, do_id_user);
272 }
273 if (view_layer->system_properties) {
274 IDP_FreeProperty_ex(view_layer->system_properties, do_id_user);
275 }
276
278
279 MEM_freeN(view_layer);
280}
281
283{
284 view_layer->basact = nullptr;
285
286 BLI_freelistN(&view_layer->object_bases);
287
288 if (view_layer->object_bases_hash) {
289 BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
290 }
291
293 layer_collection_free(view_layer, lc);
294 MEM_freeN(lc);
295 }
297}
298
299void BKE_view_layer_selected_objects_tag(const Scene *scene, ViewLayer *view_layer, const int tag)
300{
301 BKE_view_layer_synced_ensure(scene, view_layer);
303 if ((base->flag & BASE_SELECTED) != 0) {
304 base->object->flag |= tag;
305 }
306 else {
307 base->object->flag &= ~tag;
308 }
309 }
310}
311
313{
314 LISTBASE_FOREACH (LayerCollection *, lcn, lb) {
315 if (lcn == lc) {
316 return true;
317 }
318 if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
319 return true;
320 }
321 }
322 return false;
323}
324
326{
327 BKE_view_layer_synced_ensure(scene, view_layer);
329 if (base->object->type == OB_CAMERA) {
330 return base->object;
331 }
332 }
333
334 return nullptr;
335}
336
338{
339 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
340 if (find_scene_collection_in_scene_collections(&view_layer->layer_collections, lc)) {
341 return view_layer;
342 }
343 }
344
345 return nullptr;
346}
347
348/* Base */
349
350static void view_layer_bases_hash_create(ViewLayer *view_layer, const bool do_base_duplicates_fix)
351{
352 static blender::Mutex hash_lock;
353
354 if (view_layer->object_bases_hash == nullptr) {
355 std::scoped_lock lock(hash_lock);
356
357 if (view_layer->object_bases_hash == nullptr) {
359
360 LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
361 if (base->object) {
362 void **val_pp;
363 if (!BLI_ghash_ensure_p(hash, base->object, &val_pp)) {
364 *val_pp = base;
365 }
366 /* The same object has several bases.
367 *
368 * In normal cases this is a serious bug, but this is a common situation when remapping
369 * an object into another one already present in the same View Layer. While ideally we
370 * would process this case separately, for performances reasons it makes more sense to
371 * tackle it here. */
372 else if (do_base_duplicates_fix) {
373 if (view_layer->basact == base) {
374 view_layer->basact = nullptr;
375 }
376 BLI_freelinkN(&view_layer->object_bases, base);
377 }
378 else {
380 "Object '%s' has more than one entry in view layer's object bases listbase",
381 base->object->id.name + 2);
382 }
383 }
384 }
385
386 /* Assign pointer only after hash is complete. */
387 view_layer->object_bases_hash = hash;
388 }
389 }
390}
391
393{
394 BLI_assert_msg((view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
395 "View layer out of sync, invoke BKE_view_layer_synced_ensure.");
396 if (!view_layer->object_bases_hash) {
397 view_layer_bases_hash_create(view_layer, false);
398 }
399
400 return static_cast<Base *>(BLI_ghash_lookup(view_layer->object_bases_hash, ob));
401}
402
403void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
404{
405 BLI_assert(scene);
406 BLI_assert(view_layer);
407
408 BKE_view_layer_synced_ensure(scene, view_layer);
410 base->flag &= ~BASE_SELECTED;
411 }
412}
413
415{
416 view_layer->basact = selbase;
417 if ((selbase->flag & BASE_SELECTABLE) != 0) {
418 selbase->flag |= BASE_SELECTED;
419 }
420}
421
423
424/* -------------------------------------------------------------------- */
427
428static void layer_aov_copy_data(ViewLayer *view_layer_dst,
429 const ViewLayer *view_layer_src,
430 ListBase *aovs_dst,
431 const ListBase *aovs_src)
432{
433 BLI_duplicatelist(aovs_dst, aovs_src);
434
435 ViewLayerAOV *aov_dst = static_cast<ViewLayerAOV *>(aovs_dst->first);
436 const ViewLayerAOV *aov_src = static_cast<const ViewLayerAOV *>(aovs_src->first);
437
438 while (aov_dst != nullptr) {
439 BLI_assert(aov_src);
440 if (aov_src == view_layer_src->active_aov) {
441 view_layer_dst->active_aov = aov_dst;
442 }
443
444 aov_dst = aov_dst->next;
445 aov_src = aov_src->next;
446 }
447}
448
449static void layer_lightgroup_copy_data(ViewLayer *view_layer_dst,
450 const ViewLayer *view_layer_src,
451 ListBase *lightgroups_dst,
452 const ListBase *lightgroups_src)
453{
454 if (lightgroups_src != nullptr) {
455 BLI_duplicatelist(lightgroups_dst, lightgroups_src);
456 }
457
458 ViewLayerLightgroup *lightgroup_dst = static_cast<ViewLayerLightgroup *>(lightgroups_dst->first);
459 const ViewLayerLightgroup *lightgroup_src = static_cast<const ViewLayerLightgroup *>(
460 lightgroups_src->first);
461
462 while (lightgroup_dst != nullptr) {
463 BLI_assert(lightgroup_src);
464 if (lightgroup_src == view_layer_src->active_lightgroup) {
465 view_layer_dst->active_lightgroup = lightgroup_dst;
466 }
467
468 lightgroup_dst = lightgroup_dst->next;
469 lightgroup_src = lightgroup_src->next;
470 }
471}
472
473static void layer_collections_copy_data(ViewLayer *view_layer_dst,
474 const ViewLayer *view_layer_src,
475 ListBase *layer_collections_dst,
476 const ListBase *layer_collections_src)
477{
478 BLI_duplicatelist(layer_collections_dst, layer_collections_src);
479
480 LayerCollection *layer_collection_dst = static_cast<LayerCollection *>(
481 layer_collections_dst->first);
482 const LayerCollection *layer_collection_src = static_cast<const LayerCollection *>(
483 layer_collections_src->first);
484
485 while (layer_collection_dst != nullptr) {
486 layer_collections_copy_data(view_layer_dst,
487 view_layer_src,
488 &layer_collection_dst->layer_collections,
489 &layer_collection_src->layer_collections);
490
491 if (layer_collection_src == view_layer_src->active_collection) {
492 view_layer_dst->active_collection = layer_collection_dst;
493 }
494
495 layer_collection_dst = layer_collection_dst->next;
496 layer_collection_src = layer_collection_src->next;
497 }
498}
499
501 const Scene * /*scene_src*/,
502 ViewLayer *view_layer_dst,
503 const ViewLayer *view_layer_src,
504 const int flag)
505{
506 if (view_layer_dst->id_properties != nullptr) {
507 view_layer_dst->id_properties = IDP_CopyProperty_ex(view_layer_dst->id_properties, flag);
508 }
509 if (view_layer_dst->system_properties != nullptr) {
510 view_layer_dst->system_properties = IDP_CopyProperty_ex(view_layer_dst->system_properties,
511 flag);
512 }
514 &view_layer_dst->freestyle_config, &view_layer_src->freestyle_config, flag);
515
516 view_layer_dst->stats = nullptr;
517
518 /* Clear temporary data. */
519 view_layer_dst->object_bases_array = nullptr;
520 view_layer_dst->object_bases_hash = nullptr;
521
522 /* Copy layer collections and object bases. */
523 /* Inline #BLI_duplicatelist and update the active base. */
524 BLI_listbase_clear(&view_layer_dst->object_bases);
525 BLI_assert_msg((view_layer_src->flag & VIEW_LAYER_OUT_OF_SYNC) == 0,
526 "View Layer Object Base out of sync, invoke BKE_view_layer_synced_ensure.");
527 LISTBASE_FOREACH (const Base *, base_src, &view_layer_src->object_bases) {
528 Base *base_dst = static_cast<Base *>(MEM_dupallocN(base_src));
529 BLI_addtail(&view_layer_dst->object_bases, base_dst);
530 if (view_layer_src->basact == base_src) {
531 view_layer_dst->basact = base_dst;
532 }
533 }
534
535 view_layer_dst->active_collection = nullptr;
536 layer_collections_copy_data(view_layer_dst,
537 view_layer_src,
538 &view_layer_dst->layer_collections,
539 &view_layer_src->layer_collections);
540
541 LayerCollection *lc_scene_dst = static_cast<LayerCollection *>(
542 view_layer_dst->layer_collections.first);
543 lc_scene_dst->collection = scene_dst->master_collection;
544
545 BLI_listbase_clear(&view_layer_dst->aovs);
547 view_layer_dst, view_layer_src, &view_layer_dst->aovs, &view_layer_src->aovs);
548
549 BLI_listbase_clear(&view_layer_dst->lightgroups);
551 view_layer_dst, view_layer_src, &view_layer_dst->lightgroups, &view_layer_src->lightgroups);
552
554 id_us_plus((ID *)view_layer_dst->mat_override);
555 }
556}
557
558void BKE_view_layer_rename(Main *bmain, Scene *scene, ViewLayer *view_layer, const char *newname)
559{
560 char oldname[sizeof(view_layer->name)];
561
562 STRNCPY(oldname, view_layer->name);
563
564 STRNCPY_UTF8(view_layer->name, newname);
566 view_layer,
567 DATA_("ViewLayer"),
568 '.',
569 offsetof(ViewLayer, name),
570 sizeof(view_layer->name));
571
572 if (scene->nodetree) {
573 int index = BLI_findindex(&scene->view_layers, view_layer);
574
575 for (bNode *node : scene->nodetree->all_nodes()) {
576 if (node->type_legacy == CMP_NODE_R_LAYERS && node->id == nullptr) {
577 if (node->custom1 == index) {
578 STRNCPY(node->name, view_layer->name);
579 }
580 }
581 }
582 }
583
584 /* Fix all the animation data and windows which may link to this. */
585 BKE_animdata_fix_paths_rename_all(nullptr, "view_layers", oldname, view_layer->name);
586
587 /* WM can be missing on startup. */
588 wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
589 if (wm) {
590 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
591 if (win->scene == scene && STREQ(win->view_layer_name, oldname)) {
592 STRNCPY(win->view_layer_name, view_layer->name);
593 }
594 }
595 }
596
597 /* Dependency graph uses view layer name based lookups. */
599}
600
601/* LayerCollection */
602
606static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
607{
609 if (*i == number) {
610 return lc;
611 }
612
613 (*i)++;
614 }
615
617 LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
618 if (lc_nested) {
619 return lc_nested;
620 }
621 }
622 return nullptr;
623}
624
629{
630 if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
631 return true;
632 }
633
634 /* Check visibility restriction flags */
636 return true;
637 }
638
639 /* Restriction flags stay set, so we need to check parents */
640 CollectionParent *parent = static_cast<CollectionParent *>(
642
643 if (parent) {
645
646 return lc && layer_collection_hidden(view_layer, lc);
647 }
648
649 return false;
650}
651
653{
654 int i = 0;
655 return collection_from_index(&view_layer->layer_collections, index, &i);
656}
657
659{
660 return view_layer->active_collection;
661}
662
664{
665 if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
666 return false;
667 }
668
669 view_layer->active_collection = lc;
670 return true;
671}
672
674{
675 CollectionParent *parent = static_cast<CollectionParent *>(
677
678 if (parent) {
680 }
681 else {
682 lc = nullptr;
683 }
684
685 /* Don't activate excluded or hidden collections to prevent creating objects in a hidden
686 * collection from the UI */
687 if (lc && layer_collection_hidden(view_layer, lc)) {
688 return BKE_layer_collection_activate_parent(view_layer, lc);
689 }
690
691 if (!lc) {
692 lc = static_cast<LayerCollection *>(view_layer->layer_collections.first);
693 }
694
695 view_layer->active_collection = lc;
696 return lc;
697}
698
702static int collection_count(const ListBase *lb)
703{
704 int i = 0;
705 LISTBASE_FOREACH (const LayerCollection *, lc, lb) {
706 i += collection_count(&lc->layer_collections) + 1;
707 }
708 return i;
709}
710
712{
713 return collection_count(&view_layer->layer_collections);
714}
715
719static int index_from_collection(ListBase *lb, const LayerCollection *lc, int *i)
720{
721 LISTBASE_FOREACH (LayerCollection *, lcol, lb) {
722 if (lcol == lc) {
723 return *i;
724 }
725
726 (*i)++;
727 }
728
729 LISTBASE_FOREACH (LayerCollection *, lcol, lb) {
730 int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
731 if (i_nested != -1) {
732 return i_nested;
733 }
734 }
735 return -1;
736}
737
739{
740 int i = 0;
741 return index_from_collection(&view_layer->layer_collections, lc, &i);
742}
743
745
746/* -------------------------------------------------------------------- */
781
782/* NOTE: This can also be modified from several threads (e.g. during depsgraph evaluation), leading
783 * to transitional big numbers. */
784static std::atomic<int32_t> no_resync = 0;
785/* Maximum allowed levels of re-entrant calls to #BKE_layer_collection_resync_forbid. */
786[[maybe_unused]] static constexpr int no_resync_recurse_max = 16 * 256;
787
794
801
804
805 /* Temp data used to generate a queue during valid layer search. See
806 * #layer_collection_resync_find. */
808
809 /* LayerCollection and Collection wrapped by this data. */
812
813 /* Hierarchical relationships in the old, existing ViewLayer state (except for newly created
814 * layers). */
817
818 /* This layer still points to a valid collection. */
820 /* This layer is still valid as a parent, i.e. at least one of its original layer children is
821 * usable and matches one of its current children collections. */
823 /* This layer is still valid as a child, i.e. its original layer parent is usable and matches one
824 * of its current parents collections. */
826 /* This layer is still fully valid in the new collection hierarchy, i.e. itself and all of its
827 * parents fully match the current collection hierarchy.
828 * OR
829 * This layer has already been re-used to match the new collections hierarchy. */
831};
832
834 LayerCollectionResync *parent_layer_resync, LayerCollection *layer, BLI_mempool *mempool)
835{
836 LayerCollectionResync *layer_resync = static_cast<LayerCollectionResync *>(
837 BLI_mempool_calloc(mempool));
838
839 layer_resync->layer = layer;
840 layer_resync->collection = layer->collection;
841 layer_resync->parent_layer_resync = parent_layer_resync;
842 if (parent_layer_resync != nullptr) {
843 BLI_addtail(&parent_layer_resync->children_layer_resync, layer_resync);
844 }
845
846 layer_resync->is_usable = (layer->collection != nullptr);
847 layer_resync->is_valid_as_child =
848 layer_resync->is_usable && (parent_layer_resync == nullptr ||
849 (parent_layer_resync->is_usable &&
850 BLI_findptr(&parent_layer_resync->layer->collection->children,
851 layer->collection,
852 offsetof(CollectionChild, collection)) != nullptr));
853 if (layer_resync->is_valid_as_child) {
854 layer_resync->is_used = parent_layer_resync != nullptr ? parent_layer_resync->is_used : true;
855 }
856 else {
857 layer_resync->is_used = false;
858 }
859
861 layer_resync->is_valid_as_parent = layer_resync->is_usable;
862 }
863 else {
864 LISTBASE_FOREACH (LayerCollection *, child_layer, &layer->layer_collections) {
866 layer_resync, child_layer, mempool);
867 if (layer_resync->is_usable && child_layer_resync->is_valid_as_child) {
868 layer_resync->is_valid_as_parent = true;
869 }
870 }
871 }
872
873 CLOG_INFO(&LOG,
874 4,
875 "Old LayerCollection for %s is...\n\tusable: %d\n\tvalid parent: %d\n\tvalid child: "
876 "%d\n\tused: %d\n",
877 layer_resync->collection ? layer_resync->collection->id.name : "<NONE>",
878 layer_resync->is_usable,
879 layer_resync->is_valid_as_parent,
880 layer_resync->is_valid_as_child,
881 layer_resync->is_used);
882
883 return layer_resync;
884}
885
887 Collection *child_collection)
888{
889 /* Given the given parent, valid layer collection, find in the old hierarchy the best possible
890 * unused layer matching the given child collection.
891 *
892 * This uses the following heuristics:
893 * - Prefer a layer descendant of the given parent one if possible.
894 * - Prefer a layer as closely related as possible from the given parent.
895 * - Do not used layers that are not head (highest possible ancestor) of a local valid hierarchy
896 * branch, since we can assume we could then re-use its ancestor instead.
897 *
898 * A queue is used to ensure this order of preferences.
899 */
900
901 BLI_assert(layer_resync->collection != child_collection);
902 BLI_assert(child_collection != nullptr);
903
904 LayerCollectionResync *current_layer_resync = nullptr;
905 LayerCollectionResync *root_layer_resync = layer_resync;
906
907 LayerCollectionResync *queue_head = layer_resync, *queue_tail = layer_resync;
908 layer_resync->queue_next = nullptr;
909
910 while (queue_head != nullptr) {
911 current_layer_resync = queue_head;
912 queue_head = current_layer_resync->queue_next;
913
914 if (current_layer_resync->collection == child_collection &&
915 (current_layer_resync->parent_layer_resync == layer_resync ||
916 (!current_layer_resync->is_used && !current_layer_resync->is_valid_as_child)))
917 {
918 /* This layer is a valid candidate, because its collection matches the seeked one, AND:
919 * - It is a direct child of the initial given parent ('unchanged hierarchy' case), OR
920 * - It is not currently used, and not part of a valid hierarchy (sub-)chain.
921 */
922 break;
923 }
924
925 /* Else, add all its direct children for further searching. */
927 LayerCollectionResync *, child_layer_resync, &current_layer_resync->children_layer_resync)
928 {
929 /* Add to tail of the queue. */
930 queue_tail->queue_next = child_layer_resync;
931 child_layer_resync->queue_next = nullptr;
932 queue_tail = child_layer_resync;
933 if (queue_head == nullptr) {
934 queue_head = queue_tail;
935 }
936 }
937
938 /* If all descendants from current layer have been processed, go one step higher and
939 * process all of its other siblings. */
940 if (queue_head == nullptr && root_layer_resync->parent_layer_resync != nullptr) {
942 sibling_layer_resync,
943 &root_layer_resync->parent_layer_resync->children_layer_resync)
944 {
945 if (sibling_layer_resync == root_layer_resync) {
946 continue;
947 }
948 /* Add to tail of the queue. */
949 queue_tail->queue_next = sibling_layer_resync;
950 sibling_layer_resync->queue_next = nullptr;
951 queue_tail = sibling_layer_resync;
952 if (queue_head == nullptr) {
953 queue_head = queue_tail;
954 }
955 }
956 root_layer_resync = root_layer_resync->parent_layer_resync;
957 }
958
959 current_layer_resync = nullptr;
960 }
961
962 return current_layer_resync;
963}
964
966 LayerCollectionResync *layer_resync)
967{
969 LayerCollectionResync *, child_layer_resync, &layer_resync->children_layer_resync)
970 {
971 layer_collection_resync_unused_layers_free(view_layer, child_layer_resync);
972 }
973
974 if (!layer_resync->is_used) {
975 CLOG_INFO(&LOG,
976 4,
977 "Freeing unused LayerCollection for %s",
978 layer_resync->collection != nullptr ? layer_resync->collection->id.name :
979 "<Deleted Collection>");
980
981 if (layer_resync->layer == view_layer->active_collection) {
982 view_layer->active_collection = nullptr;
983 }
984
985 /* We do not want to go recursive here, this is handled through the LayerCollectionResync data
986 * wrapper. */
987 MEM_freeN(layer_resync->layer);
988 layer_resync->layer = nullptr;
989 layer_resync->collection = nullptr;
990 layer_resync->is_usable = false;
991 }
992}
993
995{
996 view_layer->flag |= VIEW_LAYER_OUT_OF_SYNC;
997}
998
999void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
1000{
1001 BLI_assert(scene);
1002 BLI_assert(view_layer);
1003
1004 if (view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) {
1005 BKE_layer_collection_sync(scene, view_layer);
1006 view_layer->flag &= ~VIEW_LAYER_OUT_OF_SYNC;
1007 }
1008}
1009
1011{
1012 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1013 BKE_view_layer_synced_ensure(scene, view_layer);
1014 }
1015}
1016
1018{
1019 for (const Scene *scene = static_cast<const Scene *>(bmain->scenes.first); scene;
1020 scene = static_cast<const Scene *>(scene->id.next))
1021 {
1023 }
1024
1025 /* NOTE: This is not (yet?) covered by the dirty tag and deferred re-sync system. */
1027}
1028
1030 LayerCollection *layer,
1031 ListBase *r_lb_new_object_bases,
1032 const short collection_restrict,
1033 const short layer_restrict,
1034 const ushort local_collections_bits)
1035{
1036 /* No need to sync objects if the collection is excluded. */
1037 if ((layer->flag & LAYER_COLLECTION_EXCLUDE) != 0) {
1038 return;
1039 }
1040
1042 if (cob->ob == nullptr) {
1043 continue;
1044 }
1045
1046 /* Tag linked object as a weak reference so we keep the object
1047 * base pointer on file load and remember hidden state. */
1048 id_lib_indirect_weak_link(&cob->ob->id);
1049
1050 void **base_p;
1051 Base *base;
1052 if (BLI_ghash_ensure_p(view_layer->object_bases_hash, cob->ob, &base_p)) {
1053 /* Move from old base list to new base list. Base might have already
1054 * been moved to the new base list and the first/last test ensure that
1055 * case also works. */
1056 base = static_cast<Base *>(*base_p);
1057 if (!ELEM(base, r_lb_new_object_bases->first, r_lb_new_object_bases->last)) {
1058 BLI_remlink(&view_layer->object_bases, base);
1059 BLI_addtail(r_lb_new_object_bases, base);
1060 }
1061 }
1062 else {
1063 /* Create new base. */
1064 base = object_base_new(cob->ob);
1065 base->local_collections_bits = local_collections_bits;
1066 *base_p = base;
1067 BLI_addtail(r_lb_new_object_bases, base);
1068 }
1069
1070 if ((collection_restrict & COLLECTION_HIDE_VIEWPORT) == 0) {
1073 if ((layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
1075 }
1076 if ((collection_restrict & COLLECTION_HIDE_SELECT) == 0) {
1078 }
1079 }
1080
1081 if ((collection_restrict & COLLECTION_HIDE_RENDER) == 0) {
1083 }
1084
1085 /* Holdout and indirect only */
1086 if (layer->flag & LAYER_COLLECTION_HOLDOUT) {
1088 }
1089 if (layer->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
1091 }
1092
1094 }
1095}
1096
1097static void layer_collection_sync(ViewLayer *view_layer,
1098 LayerCollectionResync *layer_resync,
1099 BLI_mempool *layer_resync_mempool,
1100 ListBase *r_lb_new_object_bases,
1101 const short parent_layer_flag,
1102 const short parent_collection_restrict,
1103 const short parent_layer_restrict,
1104 const ushort parent_local_collections_bits)
1105{
1106 /* This function assumes current 'parent' layer collection is already fully (re)synced and valid
1107 * regarding current Collection hierarchy.
1108 *
1109 * It will process all the children collections of the collection from the given 'parent' layer,
1110 * re-use or create layer collections for each of them, and ensure orders also match.
1111 *
1112 * Then it will ensure that the objects owned by the given parent collection have a proper base.
1113 *
1114 * NOTE: This process is recursive.
1115 */
1116
1117 /* Temporary storage for all valid (new or reused) children layers. */
1118 ListBase new_lb_layer = {nullptr, nullptr};
1119
1120 BLI_assert(layer_resync->is_used);
1121
1122 uint64_t skipped_children = 0;
1123 LISTBASE_FOREACH (CollectionChild *, child, &layer_resync->collection->children) {
1124 Collection *child_collection = child->collection;
1125 /* Collection relations may not have rebuild yet. */
1126 if (child_collection == nullptr) {
1127 skipped_children++;
1128 continue;
1129 }
1130 LayerCollectionResync *child_layer_resync = layer_collection_resync_find(layer_resync,
1131 child_collection);
1132
1133 if (child_layer_resync != nullptr) {
1134 BLI_assert(child_layer_resync->collection != nullptr);
1135 BLI_assert(child_layer_resync->layer != nullptr);
1136 BLI_assert(child_layer_resync->is_usable);
1137
1138 if (child_layer_resync->is_used) {
1139 CLOG_INFO(&LOG,
1140 4,
1141 "Found same existing LayerCollection for %s as child of %s",
1142 child_collection->id.name,
1143 layer_resync->collection->id.name);
1144 }
1145 else {
1146 CLOG_INFO(&LOG,
1147 4,
1148 "Found a valid unused LayerCollection for %s as child of %s, re-using it",
1149 child_collection->id.name,
1150 layer_resync->collection->id.name);
1151 }
1152
1153 child_layer_resync->is_used = true;
1154
1155 /* NOTE: Do not move the resync wrapper to match the new layer hierarchy, so that the old
1156 * parenting info remains available. In case a search for a valid layer in the children of
1157 * the current is required again, the old parenting hierarchy is needed as reference, not the
1158 * new one.
1159 */
1161 child_layer_resync->layer);
1162 BLI_addtail(&new_lb_layer, child_layer_resync->layer);
1163 }
1164 else {
1165 CLOG_INFO(&LOG,
1166 4,
1167 "No available LayerCollection for %s as child of %s, creating a new one",
1168 child_collection->id.name,
1169 layer_resync->collection->id.name);
1170
1171 LayerCollection *child_layer = layer_collection_add(&new_lb_layer, child_collection);
1172 child_layer->flag = parent_layer_flag;
1173
1174 child_layer_resync = static_cast<LayerCollectionResync *>(
1175 BLI_mempool_calloc(layer_resync_mempool));
1176 child_layer_resync->collection = child_collection;
1177 child_layer_resync->layer = child_layer;
1178 child_layer_resync->is_usable = true;
1179 child_layer_resync->is_used = true;
1180 child_layer_resync->is_valid_as_child = true;
1181 child_layer_resync->is_valid_as_parent = true;
1182 /* NOTE: Needs to be added to the layer_resync hierarchy so that the resync wrapper gets
1183 * freed at the end. */
1184 child_layer_resync->parent_layer_resync = layer_resync;
1185 BLI_addtail(&layer_resync->children_layer_resync, child_layer_resync);
1186 }
1187
1188 LayerCollection *child_layer = child_layer_resync->layer;
1189
1190 const ushort child_local_collections_bits = parent_local_collections_bits &
1191 child_layer->local_collections_bits;
1192
1193 /* Tag linked collection as a weak reference so we keep the layer
1194 * collection pointer on file load and remember exclude state. */
1195 id_lib_indirect_weak_link(&child_collection->id);
1196
1197 /* Collection restrict is inherited. */
1198 short child_collection_restrict = parent_collection_restrict;
1199 short child_layer_restrict = parent_layer_restrict;
1200 if (!(child_collection->flag & COLLECTION_IS_MASTER)) {
1201 child_collection_restrict |= child_collection->flag;
1202 child_layer_restrict |= child_layer->flag;
1203 }
1204
1205 /* Sync child collections. */
1206 layer_collection_sync(view_layer,
1207 child_layer_resync,
1208 layer_resync_mempool,
1209 r_lb_new_object_bases,
1210 child_layer->flag,
1211 child_collection_restrict,
1212 child_layer_restrict,
1213 child_local_collections_bits);
1214
1215 /* Layer collection exclude is not inherited. */
1216 child_layer->runtime_flag = 0;
1217 if (child_layer->flag & LAYER_COLLECTION_EXCLUDE) {
1218 continue;
1219 }
1220
1221 /* We separate restrict viewport and visible view layer because a layer collection can be
1222 * hidden in the view layer yet (locally) visible in a viewport (if it is not restricted). */
1223 if (child_collection_restrict & COLLECTION_HIDE_VIEWPORT) {
1225 }
1226
1227 if (((child_layer->runtime_flag & LAYER_COLLECTION_HIDE_VIEWPORT) == 0) &&
1228 ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0))
1229 {
1231 }
1232
1233 if (!BLI_listbase_is_empty(&child_collection->exporters) &&
1234 !(ID_IS_LINKED(&child_collection->id) || ID_IS_OVERRIDE_LIBRARY(&child_collection->id)))
1235 {
1237 }
1238 }
1239
1240 /* Replace layer collection list with new one. */
1241 layer_resync->layer->layer_collections = new_lb_layer;
1242 BLI_assert(BLI_listbase_count(&layer_resync->collection->children) - skipped_children ==
1243 BLI_listbase_count(&new_lb_layer));
1244 UNUSED_VARS_NDEBUG(skipped_children);
1245
1246 /* Update bases etc. for objects. */
1248 layer_resync->layer,
1249 r_lb_new_object_bases,
1250 parent_collection_restrict,
1251 parent_layer_restrict,
1252 parent_local_collections_bits);
1253}
1254
1255#ifndef NDEBUG
1257{
1258 bool is_valid = true;
1259
1260 if (layer == nullptr) {
1261 layer = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1262 }
1263
1264 /* Only check for a collection's objects if its layer is not excluded. */
1265 if ((layer->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1267 if (cob->ob == nullptr) {
1268 continue;
1269 }
1270 if (BLI_ghash_lookup(view_layer->object_bases_hash, cob->ob) == nullptr) {
1271 CLOG_FATAL(
1272 &LOG,
1273 "Object '%s' from collection '%s' has no entry in view layer's object bases cache",
1274 cob->ob->id.name + 2,
1275 layer->collection->id.name + 2);
1276 is_valid = false;
1277 break;
1278 }
1279 }
1280 }
1281
1282 if (is_valid) {
1283 LISTBASE_FOREACH (LayerCollection *, layer_child, &layer->layer_collections) {
1284 if (!view_layer_objects_base_cache_validate(view_layer, layer_child)) {
1285 is_valid = false;
1286 break;
1287 }
1288 }
1289 }
1290
1291 return is_valid;
1292}
1293#else
1294static bool view_layer_objects_base_cache_validate(ViewLayer * /*view_layer*/,
1295 LayerCollection * /*layer*/)
1296{
1297 return true;
1298}
1299#endif
1300
1302{
1303 LayerCollection *first_layer_collection = static_cast<LayerCollection *>(
1304 view_layer->layer_collections.first);
1305 if (BLI_listbase_count_at_most(&view_layer->layer_collections, 2) > 1 ||
1306 first_layer_collection->collection != scene->master_collection)
1307 {
1308 /* In some cases (from older files) we do have a master collection, but no matching layer,
1309 * instead all the children of the master collection have their layer collections in the
1310 * viewlayer's list. This is not a valid situation, add a layer for the master collection and
1311 * add all existing first-level layers as children of that new master layer. */
1312 ListBase layer_collections = view_layer->layer_collections;
1314 LayerCollection *master_layer_collection = layer_collection_add(&view_layer->layer_collections,
1315 scene->master_collection);
1316 master_layer_collection->layer_collections = layer_collections;
1317 }
1318}
1319
1320void BKE_layer_collection_sync(const Scene *scene, ViewLayer *view_layer)
1321{
1322 if (no_resync > 0) {
1323 return;
1324 }
1325
1326 if (!scene->master_collection) {
1327 /* Happens for old files that don't have versioning applied yet. */
1328 return;
1329 }
1330
1331 if (BLI_listbase_is_empty(&view_layer->layer_collections)) {
1332 /* In some cases (from older files, or when creating a new ViewLayer from
1333 * #BKE_view_layer_add), we do have a master collection, yet no matching layer. Create the
1334 * master one here, so that the rest of the code can work as expected. */
1336 }
1337
1338#ifndef NDEBUG
1339 {
1341 "ViewLayer's first level of children layer collections should always have "
1342 "exactly one item");
1343
1344 LayerCollection *first_layer_collection = static_cast<LayerCollection *>(
1345 view_layer->layer_collections.first);
1346 BLI_assert_msg(first_layer_collection->collection == scene->master_collection,
1347 "ViewLayer's first layer collection should always be the one for the scene's "
1348 "master collection");
1349 }
1350#endif
1351
1352 /* Free cache. */
1353 MEM_SAFE_FREE(view_layer->object_bases_array);
1354
1355 /* Create object to base hash if it does not exist yet. */
1356 if (!view_layer->object_bases_hash) {
1357 view_layer_bases_hash_create(view_layer, false);
1358 }
1359
1360 /* Clear visible and selectable flags to be reset. */
1361 LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1362 base->flag &= ~g_base_collection_flags;
1363 base->flag_from_collection &= ~g_base_collection_flags;
1364 }
1365
1366 /* Generate temporary data representing the old layers hierarchy, and how well it matches the
1367 * new collections hierarchy. */
1368 BLI_mempool *layer_resync_mempool = BLI_mempool_create(
1369 sizeof(LayerCollectionResync), 1024, 1024, BLI_MEMPOOL_NOP);
1371 nullptr,
1372 static_cast<LayerCollection *>(view_layer->layer_collections.first),
1373 layer_resync_mempool);
1374
1375 /* Clear the cached flag indicating if the view layer has a collection exporter set. */
1377
1378 /* Generate new layer connections and object bases when collections changed. */
1379 ListBase new_object_bases{};
1380 const short parent_exclude = 0, parent_restrict = 0, parent_layer_restrict = 0;
1381 layer_collection_sync(view_layer,
1382 master_layer_resync,
1383 layer_resync_mempool,
1384 &new_object_bases,
1385 parent_exclude,
1386 parent_restrict,
1387 parent_layer_restrict,
1388 ~0);
1389
1390 layer_collection_resync_unused_layers_free(view_layer, master_layer_resync);
1391 BLI_mempool_destroy(layer_resync_mempool);
1392 master_layer_resync = nullptr;
1393
1394 /* Any remaining object bases are to be removed. */
1395 LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1396 if (view_layer->basact == base) {
1397 view_layer->basact = nullptr;
1398 }
1399
1400 if (base->object) {
1401 /* Those asserts are commented, since they are too expensive to perform even in debug, as
1402 * this layer resync function currently gets called way too often. */
1403#if 0
1404 BLI_assert(BLI_findindex(&new_object_bases, base) == -1);
1405 BLI_assert(BLI_findptr(&new_object_bases, base->object, offsetof(Base, object)) == nullptr);
1406#endif
1407 BLI_ghash_remove(view_layer->object_bases_hash, base->object, nullptr, nullptr);
1408 }
1409 }
1410
1411 BLI_freelistN(&view_layer->object_bases);
1412 view_layer->object_bases = new_object_bases;
1413
1414 view_layer_objects_base_cache_validate(view_layer, nullptr);
1415
1416 LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1417 BKE_base_eval_flags(base);
1418 }
1419
1420 /* Always set a valid active collection. */
1422 if (active && layer_collection_hidden(view_layer, active)) {
1424 }
1425 else if (active == nullptr) {
1426 view_layer->active_collection = static_cast<LayerCollection *>(
1427 view_layer->layer_collections.first);
1428 }
1429}
1430
1432{
1433 if (no_resync > 0) {
1434 return;
1435 }
1436
1437 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1439 }
1440}
1441
1443{
1444 if (no_resync > 0) {
1445 return;
1446 }
1447
1448 /* TODO: if a single collection changed, figure out which
1449 * scenes it belongs to and only update those. */
1450
1451 /* TODO: optimize for file load so only linked collections get checked? */
1452
1453 for (const Scene *scene = static_cast<const Scene *>(bmain->scenes.first); scene;
1454 scene = static_cast<const Scene *>(scene->id.next))
1455 {
1457 }
1458
1460}
1461
1463{
1464 if (no_resync > 0) {
1465 return;
1466 }
1467
1468 /* On remapping of object or collection pointers free caches. */
1469 /* TODO: try to make this faster */
1470
1472
1473 for (Scene *scene = static_cast<Scene *>(bmain->scenes.first); scene;
1474 scene = static_cast<Scene *>(scene->id.next))
1475 {
1476 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1477 MEM_SAFE_FREE(view_layer->object_bases_array);
1478
1479 if (view_layer->object_bases_hash) {
1480 BLI_ghash_free(view_layer->object_bases_hash, nullptr, nullptr);
1481 view_layer->object_bases_hash = nullptr;
1482 }
1483
1484 /* Directly re-create the mapping here, so that we can also deal with duplicates in
1485 * `view_layer->object_bases` list of bases properly. This is the only place where such
1486 * duplicates should be fixed, and not considered as a critical error. */
1487 view_layer_bases_hash_create(view_layer, true);
1488 }
1489
1490 DEG_id_tag_update_ex((Main *)bmain, &scene->master_collection->id, ID_RECALC_SYNC_TO_EVAL);
1491 DEG_id_tag_update_ex((Main *)bmain, &scene->id, ID_RECALC_SYNC_TO_EVAL);
1492 }
1493
1494 for (Collection *collection = static_cast<Collection *>(bmain->collections.first); collection;
1495 collection = static_cast<Collection *>(collection->id.next))
1496 {
1497 DEG_id_tag_update_ex((Main *)bmain, &collection->id, ID_RECALC_SYNC_TO_EVAL);
1498 }
1499
1501}
1502
1504
1505/* -------------------------------------------------------------------- */
1508
1510 ViewLayer *view_layer,
1511 LayerCollection *lc,
1512 bool deselect)
1513{
1515 return false;
1516 }
1517
1518 bool changed = false;
1519
1520 if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
1521 BKE_view_layer_synced_ensure(scene, view_layer);
1523 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1524
1525 if (base) {
1526 if (deselect) {
1527 if (base->flag & BASE_SELECTED) {
1528 base->flag &= ~BASE_SELECTED;
1529 changed = true;
1530 }
1531 }
1532 else {
1533 if ((base->flag & BASE_SELECTABLE) && !(base->flag & BASE_SELECTED)) {
1534 base->flag |= BASE_SELECTED;
1535 changed = true;
1536 }
1537 }
1538 }
1539 }
1540 }
1541
1543 changed |= BKE_layer_collection_objects_select(scene, view_layer, iter, deselect);
1544 }
1545
1546 return changed;
1547}
1548
1550 ViewLayer *view_layer,
1551 LayerCollection *lc)
1552{
1554 return false;
1555 }
1556
1557 if (!(lc->flag & LAYER_COLLECTION_EXCLUDE)) {
1558 BKE_view_layer_synced_ensure(scene, view_layer);
1560 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1561
1562 if (base && (base->flag & BASE_SELECTED) &&
1564 {
1565 return true;
1566 }
1567 }
1568 }
1569
1571 if (BKE_layer_collection_has_selected_objects(scene, view_layer, iter)) {
1572 return true;
1573 }
1574 }
1575
1576 return false;
1577}
1578
1580 LayerCollection *lc_child)
1581{
1582 if (lc_parent == lc_child) {
1583 return true;
1584 }
1585
1586 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
1587 if (BKE_layer_collection_has_layer_collection(lc_iter, lc_child)) {
1588 return true;
1589 }
1590 }
1591 return false;
1592}
1593
1595
1596/* -------------------------------------------------------------------- */
1599
1600void BKE_base_set_visible(Scene *scene, ViewLayer *view_layer, Base *base, bool extend)
1601{
1602 if (!extend) {
1603 /* Make only one base visible. */
1604 BKE_view_layer_synced_ensure(scene, view_layer);
1605 LISTBASE_FOREACH (Base *, other, BKE_view_layer_object_bases_get(view_layer)) {
1606 other->flag |= BASE_HIDDEN;
1607 }
1608
1609 base->flag &= ~BASE_HIDDEN;
1610 }
1611 else {
1612 /* Toggle visibility of one base. */
1613 base->flag ^= BASE_HIDDEN;
1614 }
1615
1617}
1618
1619bool BKE_base_is_visible(const View3D *v3d, const Base *base)
1620{
1622 return false;
1623 }
1624
1625 if (v3d == nullptr) {
1627 }
1628
1629 if ((v3d->localvd) && ((v3d->local_view_uid & base->local_view_bits) == 0)) {
1630 return false;
1631 }
1632
1633 if (((1 << (base->object->type)) & v3d->object_type_exclude_viewport) != 0) {
1634 return false;
1635 }
1636
1637 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1638 return (v3d->local_collections_uid & base->local_collections_bits) != 0;
1639 }
1640
1642}
1643
1645{
1646 BLI_assert(v3d != nullptr);
1647
1649 return false;
1650 }
1651
1652 if ((v3d->object_type_exclude_viewport & (1 << ob->type)) != 0) {
1653 return false;
1654 }
1655
1656 if (v3d->localvd && ((v3d->local_view_uid & ob->base_local_view_bits) == 0)) {
1657 return false;
1658 }
1659
1660 if ((v3d->flag & V3D_LOCAL_COLLECTIONS) &&
1661 ((v3d->local_collections_uid & ob->runtime->local_collections_bits) == 0))
1662 {
1663 return false;
1664 }
1665
1666 /* If not using local collection the object may still be in a hidden collection. */
1667 if ((v3d->flag & V3D_LOCAL_COLLECTIONS) == 0) {
1669 }
1670
1671 return true;
1672}
1673
1675
1676/* -------------------------------------------------------------------- */
1679
1681{
1682 lc->flag |= flag;
1685 }
1686}
1687
1689{
1690 lc->flag &= ~flag;
1693 }
1694}
1695
1697 ViewLayer *view_layer,
1698 LayerCollection *lc,
1699 bool extend)
1700{
1701 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1702 bool hide_it = extend && (lc->runtime_flag & LAYER_COLLECTION_VISIBLE_VIEW_LAYER);
1703
1704 if (!extend) {
1705 /* Hide all collections. */
1706 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1708 }
1709 }
1710
1711 /* Make all the direct parents visible. */
1712 if (hide_it) {
1714 }
1715 else {
1716 LayerCollection *lc_parent = lc;
1717 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1719 lc_parent = lc_iter;
1720 break;
1721 }
1722 }
1723
1724 while (lc_parent != lc) {
1725 lc_parent->flag &= ~LAYER_COLLECTION_HIDE;
1726
1727 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
1729 lc_parent = lc_iter;
1730 break;
1731 }
1732 }
1733 }
1734
1735 /* Make all the children visible, but respect their disable state. */
1737
1738 BKE_layer_collection_activate(view_layer, lc);
1739 }
1740
1742}
1743
1745 const int local_collections_uid)
1746{
1747 layer_collection->local_collections_bits |= local_collections_uid;
1748 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1749 layer_collection_local_visibility_set_recursive(child, local_collections_uid);
1750 }
1751}
1752
1754 const int local_collections_uid)
1755{
1756 layer_collection->local_collections_bits &= ~local_collections_uid;
1757 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1758 layer_collection_local_visibility_unset_recursive(child, local_collections_uid);
1759 }
1760}
1761
1762static void layer_collection_local_sync(const Scene *scene,
1763 ViewLayer *view_layer,
1764 LayerCollection *layer_collection,
1765 const ushort local_collections_uid,
1766 bool visible)
1767{
1768 if ((layer_collection->local_collections_bits & local_collections_uid) == 0) {
1769 visible = false;
1770 }
1771
1772 if (visible) {
1773 LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) {
1774 if (cob->ob == nullptr) {
1775 continue;
1776 }
1777
1778 BKE_view_layer_synced_ensure(scene, view_layer);
1779 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1780 base->local_collections_bits |= local_collections_uid;
1781 }
1782 }
1783
1784 LISTBASE_FOREACH (LayerCollection *, child, &layer_collection->layer_collections) {
1785 if ((child->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1786 layer_collection_local_sync(scene, view_layer, child, local_collections_uid, visible);
1787 }
1788 }
1789}
1790
1791void BKE_layer_collection_local_sync(const Scene *scene, ViewLayer *view_layer, const View3D *v3d)
1792{
1793 if (no_resync > 0) {
1794 return;
1795 }
1796
1797 const ushort local_collections_uid = v3d->local_collections_uid;
1798
1799 /* Reset flags and set the bases visible by default. */
1800 BKE_view_layer_synced_ensure(scene, view_layer);
1802 base->local_collections_bits &= ~local_collections_uid;
1803 }
1804
1805 LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
1806 layer_collection_local_sync(scene, view_layer, layer_collection, local_collections_uid, true);
1807 }
1808}
1809
1811{
1812 if (no_resync > 0) {
1813 return;
1814 }
1815
1816 LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
1817 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
1818 LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
1819 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
1820 if (area->spacetype != SPACE_VIEW3D) {
1821 continue;
1822 }
1823 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
1824 if (v3d->flag & V3D_LOCAL_COLLECTIONS) {
1825 BKE_layer_collection_local_sync(scene, view_layer, v3d);
1826 }
1827 }
1828 }
1829 }
1830 }
1831}
1832
1834 const Scene *scene, ViewLayer *view_layer, const View3D *v3d, LayerCollection *lc, bool extend)
1835{
1836 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1837 bool hide_it = extend && ((v3d->local_collections_uid & lc->local_collections_bits) != 0);
1838
1839 if (!extend) {
1840 /* Hide all collections. */
1841 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1843 }
1844 }
1845
1846 /* Make all the direct parents visible. */
1847 if (hide_it) {
1849 }
1850 else {
1851 LayerCollection *lc_parent = lc;
1852 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1854 lc_parent = lc_iter;
1855 break;
1856 }
1857 }
1858
1859 while (lc_parent != lc) {
1861
1862 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) {
1864 lc_parent = lc_iter;
1865 break;
1866 }
1867 }
1868 }
1869
1870 /* Make all the children visible. */
1872 }
1873
1874 BKE_layer_collection_local_sync(scene, view_layer, v3d);
1875}
1876
1878 ViewLayer *view_layer,
1879 LayerCollection *lc)
1880{
1881 if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1882 BKE_view_layer_synced_ensure(scene, view_layer);
1884 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1885 base->flag &= ~BASE_HIDDEN;
1886 }
1887 }
1889 layer_collection_bases_show_recursive(scene, view_layer, lc_iter);
1890 }
1891}
1892
1894 ViewLayer *view_layer,
1895 LayerCollection *lc)
1896{
1897 if ((lc->flag & LAYER_COLLECTION_EXCLUDE) == 0) {
1898 BKE_view_layer_synced_ensure(scene, view_layer);
1900 Base *base = BKE_view_layer_base_find(view_layer, cob->ob);
1901 base->flag |= BASE_HIDDEN;
1902 }
1903 }
1905 layer_collection_bases_hide_recursive(scene, view_layer, lc_iter);
1906 }
1907}
1908
1910 ViewLayer *view_layer,
1911 LayerCollection *lc,
1912 const bool visible,
1913 const bool hierarchy)
1914{
1915 if (hierarchy) {
1916 if (visible) {
1918 layer_collection_bases_show_recursive(scene, view_layer, lc);
1919 }
1920 else {
1922 layer_collection_bases_hide_recursive(scene, view_layer, lc);
1923 }
1924 }
1925 else {
1926 if (visible) {
1928 }
1929 else {
1931 }
1932 }
1933}
1934
1940 const int flag,
1941 const bool value,
1942 const bool restore_flag)
1943{
1945 /* For exclude flag, we remember the state the children had before
1946 * excluding and restoring it when enabling the parent collection again. */
1947 if (value) {
1948 if (restore_flag) {
1951 }
1952 else {
1954 }
1955
1956 lc->flag |= flag;
1957 }
1958 else {
1960 lc->flag &= ~flag;
1961 }
1962 }
1963 }
1964 else {
1965 SET_FLAG_FROM_TEST(lc->flag, value, flag);
1966 }
1967
1969 layer_collection_flag_recursive_set(nlc, flag, value, true);
1970 }
1971}
1972
1973void BKE_layer_collection_set_flag(LayerCollection *lc, const int flag, const bool value)
1974{
1975 layer_collection_flag_recursive_set(lc, flag, value, false);
1976}
1977
1978/* ---------------------------------------------------------------------- */
1979
1981 const Collection *collection)
1982{
1983 if (lc->collection == collection) {
1984 return lc;
1985 }
1986
1989 if (found) {
1990 return found;
1991 }
1992 }
1993 return nullptr;
1994}
1995
1997 const Collection *collection)
1998{
1999 LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) {
2001 collection);
2002 if (found != nullptr) {
2003 return found;
2004 }
2005 }
2006 return nullptr;
2007}
2008
2009bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection *collection)
2010{
2011 return BKE_layer_collection_first_from_scene_collection(view_layer, collection) != nullptr;
2012}
2013
2015{
2016 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2017 BKE_view_layer_synced_ensure(scene, view_layer);
2018 Base *base = BKE_view_layer_base_find(view_layer, ob);
2019 if (base) {
2020 return true;
2021 }
2022 }
2023 return false;
2024}
2025
2027
2028/* Iterators */
2029
2030/* -------------------------------------------------------------------- */
2033
2038
2039static bool object_bases_iterator_is_valid(const View3D *v3d, Base *base, const int flag)
2040{
2041 BLI_assert((v3d == nullptr) || (v3d->spacetype == SPACE_VIEW3D));
2042
2043 /* Any flag satisfies the condition. */
2044 if (flag == ~0) {
2045 return (base->flag != 0);
2046 }
2047
2048 /* Flags may be more than one flag, so we can't check != 0. */
2049 return BASE_VISIBLE(v3d, base) && ((base->flag & flag) == flag);
2050}
2051
2052static void object_bases_iterator_begin(BLI_Iterator *iter, void *data_in_v, const int flag)
2053{
2054 ObjectsVisibleIteratorData *data_in = static_cast<ObjectsVisibleIteratorData *>(data_in_v);
2055 ViewLayer *view_layer = data_in->view_layer;
2056 const View3D *v3d = data_in->v3d;
2057 Base *base = static_cast<Base *>(BKE_view_layer_object_bases_get(view_layer)->first);
2058
2059 /* when there are no objects */
2060 if (base == nullptr) {
2061 iter->data = nullptr;
2062 iter->valid = false;
2063 return;
2064 }
2065
2067 iter->data = data;
2068
2069 data->v3d = v3d;
2070 data->base = base;
2071
2072 if (object_bases_iterator_is_valid(v3d, base, flag) == false) {
2074 }
2075 else {
2076 iter->current = base;
2077 }
2078}
2079
2080static void object_bases_iterator_next(BLI_Iterator *iter, const int flag)
2081{
2083 Base *base = data->base->next;
2084
2085 while (base) {
2086 if (object_bases_iterator_is_valid(data->v3d, base, flag)) {
2087 iter->current = base;
2088 data->base = base;
2089 return;
2090 }
2091 base = base->next;
2092 }
2093
2094 iter->valid = false;
2095}
2096
2098{
2099 MEM_SAFE_FREE(iter->data);
2100}
2101
2102static void objects_iterator_begin(BLI_Iterator *iter, void *data_in, const int flag)
2103{
2104 object_bases_iterator_begin(iter, data_in, flag);
2105
2106 if (iter->valid) {
2107 iter->current = ((Base *)iter->current)->object;
2108 }
2109}
2110
2111static void objects_iterator_next(BLI_Iterator *iter, const int flag)
2112{
2114
2115 if (iter->valid) {
2116 iter->current = ((Base *)iter->current)->object;
2117 }
2118}
2119
2121{
2123}
2124
2126
2127/* -------------------------------------------------------------------- */
2131
2137
2142
2147
2149
2150/* -------------------------------------------------------------------- */
2153
2155{
2156 objects_iterator_begin(iter, data_in, 0);
2157}
2158
2163
2168
2170
2171/* -------------------------------------------------------------------- */
2174
2176{
2179 if (iter->valid) {
2180 if (BKE_object_is_libdata((Object *)iter->current) == false) {
2181 /* First object is valid (selectable and not libdata) -> all good. */
2182 return;
2183 }
2184
2185 /* Object is selectable but not editable -> search for another one. */
2187 }
2188}
2189
2191{
2192 /* Search while there are objects and the one we have is not editable (editable = not libdata).
2193 */
2194 do {
2196 } while (iter->valid && BKE_object_is_libdata((Object *)iter->current) != false);
2197}
2198
2203
2205
2206/* -------------------------------------------------------------------- */
2209
2215
2220
2225
2227
2228/* -------------------------------------------------------------------- */
2231
2233{
2234 object_bases_iterator_begin(iter, data_in, 0);
2235}
2236
2241
2246
2248
2249/* -------------------------------------------------------------------- */
2252
2254{
2255 return (base->object->type == data->object_type) &&
2256 (base->object->mode & data->object_mode) != 0;
2257}
2258
2260{
2261 ObjectsInModeIteratorData *data = static_cast<ObjectsInModeIteratorData *>(data_in);
2262 Base *base = data->base_active;
2263
2264 /* In this case the result will always be empty, the caller must check for no mode. */
2265 BLI_assert(data->object_mode != 0);
2266
2267 /* when there are no objects */
2268 if (base == nullptr) {
2269 iter->valid = false;
2270 return;
2271 }
2272 iter->data = data_in;
2273 iter->current = base;
2274
2275 /* default type is active object type */
2276 if (data->object_type < 0) {
2277 data->object_type = base->object->type;
2278 }
2279
2280 if (!(base_is_in_mode(data, base) && BKE_base_is_visible(data->v3d, base))) {
2282 }
2283}
2284
2286{
2288 Base *base = static_cast<Base *>(iter->current);
2289
2290 if (base == data->base_active) {
2291 /* first step */
2292 base = static_cast<Base *>(data->view_layer->object_bases.first);
2293 if ((base == data->base_active) && BKE_base_is_visible(data->v3d, base)) {
2294 base = base->next;
2295 }
2296 }
2297 else {
2298 base = base->next;
2299 }
2300
2301 while (base) {
2302 if ((base != data->base_active) && base_is_in_mode(data, base) &&
2303 BKE_base_is_visible(data->v3d, base))
2304 {
2305 iter->current = base;
2306 return;
2307 }
2308 base = base->next;
2309 }
2310 iter->valid = false;
2311}
2312
2314{
2315 /* do nothing */
2316}
2317
2319
2320/* -------------------------------------------------------------------- */
2323
2325{
2326 /* Apply collection flags. */
2329
2330 /* Apply object restrictions. */
2331 const int object_restrict = base->object->visibility_flag;
2332 if (object_restrict & OB_HIDE_VIEWPORT) {
2334 }
2335 if (object_restrict & OB_HIDE_RENDER) {
2336 base->flag &= ~BASE_ENABLED_RENDER;
2337 }
2338 if (object_restrict & OB_HIDE_SELECT) {
2339 base->flag &= ~BASE_SELECTABLE;
2340 }
2341
2342 /* Apply viewport visibility by default. The dependency graph for render
2343 * can change these again, but for tools we always want the viewport
2344 * visibility to be in sync regardless if depsgraph was evaluated. */
2345 if (!(base->flag & BASE_ENABLED_VIEWPORT) || (base->flag & BASE_HIDDEN)) {
2348 }
2349
2350 /* Deselect unselectable objects. */
2351 if (!(base->flag & BASE_SELECTABLE)) {
2352 base->flag &= ~BASE_SELECTED;
2353 }
2354}
2355
2356static void layer_eval_view_layer(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer)
2357{
2358 DEG_debug_print_eval(depsgraph, __func__, view_layer->name, view_layer);
2359
2360 /* Create array of bases, for fast index-based lookup. */
2361 BKE_view_layer_synced_ensure(scene, view_layer);
2362 const int num_object_bases = BLI_listbase_count(BKE_view_layer_object_bases_get(view_layer));
2363 MEM_SAFE_FREE(view_layer->object_bases_array);
2364 view_layer->object_bases_array = MEM_malloc_arrayN<Base *>(size_t(num_object_bases),
2365 "view_layer->object_bases_array");
2366 int base_index = 0;
2368 view_layer->object_bases_array[base_index++] = base;
2369 }
2370}
2371
2372void BKE_layer_eval_view_layer_indexed(Depsgraph *depsgraph, Scene *scene, int view_layer_index)
2373{
2374 BLI_assert(view_layer_index >= 0);
2375 ViewLayer *view_layer = static_cast<ViewLayer *>(
2376 BLI_findlink(&scene->view_layers, view_layer_index));
2377 BLI_assert(view_layer != nullptr);
2378 layer_eval_view_layer(depsgraph, scene, view_layer);
2379}
2380
2382
2383/* -------------------------------------------------------------------- */
2386
2388{
2389 LISTBASE_FOREACH (LayerCollection *, lc, lb) {
2390 BLO_write_struct(writer, LayerCollection, lc);
2391
2392 write_layer_collections(writer, &lc->layer_collections);
2393 }
2394}
2395
2396void BKE_view_layer_blend_write(BlendWriter *writer, const Scene *scene, ViewLayer *view_layer)
2397{
2398 BKE_view_layer_synced_ensure(scene, view_layer);
2399 BLO_write_struct(writer, ViewLayer, view_layer);
2401
2402 if (view_layer->id_properties) {
2403 IDP_BlendWrite(writer, view_layer->id_properties);
2404 }
2405 /* Never write system_properties in Blender 4.5, will be reset to `nullptr` by reading code (by
2406 * the matching call to #BLO_read_struct). */
2407
2410 }
2411
2413 BLO_write_struct(writer, FreestyleLineSet, fls);
2414 }
2415 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2416 BLO_write_struct(writer, ViewLayerAOV, aov);
2417 }
2418 LISTBASE_FOREACH (ViewLayerLightgroup *, lightgroup, &view_layer->lightgroups) {
2419 BLO_write_struct(writer, ViewLayerLightgroup, lightgroup);
2420 }
2421 write_layer_collections(writer, &view_layer->layer_collections);
2422}
2423
2425 ViewLayer *view_layer,
2426 ListBase *lb,
2427 bool master,
2428 bool &active_collection_found)
2429{
2431 LISTBASE_FOREACH (LayerCollection *, lc, lb) {
2432 /* Master collection is not a real data-block. */
2433 if (master) {
2434 BLO_read_struct(reader, Collection, &lc->collection);
2435 }
2436
2437 if (lc == view_layer->active_collection) {
2438 active_collection_found = true;
2439 }
2440
2442 reader, view_layer, &lc->layer_collections, false, active_collection_found);
2443 }
2444}
2445
2447{
2448 view_layer->stats = nullptr;
2449 BLO_read_struct_list(reader, Base, &view_layer->object_bases);
2450 BLO_read_struct(reader, Base, &view_layer->basact);
2451
2452 bool active_collection_found = false;
2453 BLO_read_struct(reader, LayerCollection, &view_layer->active_collection);
2454
2456 reader, view_layer, &view_layer->layer_collections, true, active_collection_found);
2457
2458 if (!active_collection_found) {
2459 /* Ensure pointer is valid, in case of corrupt blend file. */
2460 view_layer->active_collection = static_cast<LayerCollection *>(
2461 view_layer->layer_collections.first);
2462 }
2463
2464 BLO_read_struct(reader, IDProperty, &view_layer->id_properties);
2465 IDP_BlendDataRead(reader, &view_layer->id_properties);
2466 BLO_read_struct(reader, IDProperty, &view_layer->system_properties);
2467 IDP_BlendDataRead(reader, &view_layer->system_properties);
2468
2471
2472 BLO_read_struct_list(reader, ViewLayerAOV, &view_layer->aovs);
2473 BLO_read_struct(reader, ViewLayerAOV, &view_layer->active_aov);
2474
2477
2478 view_layer->object_bases_array = nullptr;
2479 view_layer->object_bases_hash = nullptr;
2480}
2481
2483 ID * /*self_id*/,
2484 ViewLayer *view_layer)
2485{
2486 LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) {
2487 if (base->object == nullptr) {
2488 /* Free in case linked object got lost. */
2489 BLI_freelinkN(&view_layer->object_bases, base);
2490 if (view_layer->basact == base) {
2491 view_layer->basact = nullptr;
2492 }
2493 }
2494 }
2495}
2496
2498
2499/* -------------------------------------------------------------------- */
2502
2504{
2505 ViewLayerAOV *aov = view_layer->active_aov;
2506 if (aov == nullptr) {
2507 return;
2508 }
2509
2510 /* Don't allow dots, it's incompatible with OpenEXR convention to store channels
2511 * as "layer.pass.channel". */
2512 BLI_string_replace_char(aov->name, '.', '_');
2514 &view_layer->aovs, aov, DATA_("AOV"), '_', offsetof(ViewLayerAOV, name), sizeof(aov->name));
2515}
2516
2518{
2519 if (aov != nullptr) {
2520 BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1);
2521 view_layer->active_aov = aov;
2522 }
2523 else {
2524 view_layer->active_aov = nullptr;
2525 }
2526}
2527
2529{
2530 ViewLayerAOV *aov;
2531 aov = MEM_callocN<ViewLayerAOV>(__func__);
2532 aov->type = AOV_TYPE_COLOR;
2533 STRNCPY_UTF8(aov->name, DATA_("AOV"));
2534 BLI_addtail(&view_layer->aovs, aov);
2535 viewlayer_aov_active_set(view_layer, aov);
2537 return aov;
2538}
2539
2541{
2542 BLI_assert(BLI_findindex(&view_layer->aovs, aov) != -1);
2543 BLI_assert(aov != nullptr);
2544 if (view_layer->active_aov == aov) {
2545 if (aov->next) {
2546 viewlayer_aov_active_set(view_layer, aov->next);
2547 }
2548 else {
2549 viewlayer_aov_active_set(view_layer, aov->prev);
2550 }
2551 }
2552 BLI_freelinkN(&view_layer->aovs, aov);
2553}
2554
2556{
2557 viewlayer_aov_active_set(view_layer, aov);
2558}
2559
2560static void bke_view_layer_verify_aov_cb(void *userdata,
2561 Scene * /*scene*/,
2562 ViewLayer * /*view_layer*/,
2563 const char *name,
2564 int /*channels*/,
2565 const char * /*chanid*/,
2566 eNodeSocketDatatype /*type*/)
2567{
2568 GHash *name_count = static_cast<GHash *>(userdata);
2569 void **value_p;
2570 void *key = BLI_strdup(name);
2571
2572 if (!BLI_ghash_ensure_p(name_count, key, &value_p)) {
2573 *value_p = POINTER_FROM_INT(1);
2574 }
2575 else {
2576 int value = POINTER_AS_INT(*value_p);
2577 value++;
2578 *value_p = POINTER_FROM_INT(value);
2579 MEM_freeN(key);
2580 }
2581}
2582
2583void BKE_view_layer_verify_aov(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
2584{
2586
2587 GHash *name_count = BLI_ghash_str_new(__func__);
2588 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2589 /* Disable conflict flag, so that the AOV is included when iterating over all passes below. */
2590 aov->flag &= ~AOV_CONFLICT;
2591 }
2593 engine, scene, view_layer, bke_view_layer_verify_aov_cb, name_count);
2594 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2595 void **value_p = static_cast<void **>(BLI_ghash_lookup(name_count, aov->name));
2596 int count = POINTER_AS_INT(value_p);
2597 SET_FLAG_FROM_TEST(aov->flag, count > 1, AOV_CONFLICT);
2598 }
2599 BLI_ghash_free(name_count, MEM_freeN, nullptr);
2600}
2601
2603{
2604 LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
2605 if ((aov->flag & AOV_CONFLICT) == 0) {
2606 return true;
2607 }
2608 }
2609 return false;
2610}
2611
2613{
2614 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2615 if (BLI_findindex(&view_layer->aovs, aov) != -1) {
2616 return view_layer;
2617 }
2618 }
2619 return nullptr;
2620}
2621
2623
2624/* -------------------------------------------------------------------- */
2627
2629 ViewLayerLightgroup *lightgroup)
2630{
2631 /* Don't allow dots, it's incompatible with OpenEXR convention to store channels
2632 * as "layer.pass.channel". */
2633 BLI_string_replace_char(lightgroup->name, '.', '_');
2634 BLI_uniquename(&view_layer->lightgroups,
2635 lightgroup,
2636 DATA_("Lightgroup"),
2637 '_',
2639 sizeof(lightgroup->name));
2640}
2641
2643{
2644 if (lightgroup != nullptr) {
2645 BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1);
2646 view_layer->active_lightgroup = lightgroup;
2647 }
2648 else {
2649 view_layer->active_lightgroup = nullptr;
2650 }
2651}
2652
2654{
2655 ViewLayerLightgroup *lightgroup;
2656 lightgroup = MEM_callocN<ViewLayerLightgroup>(__func__);
2657 STRNCPY_UTF8(lightgroup->name, (name && name[0]) ? name : DATA_("Lightgroup"));
2658 BLI_addtail(&view_layer->lightgroups, lightgroup);
2659 viewlayer_lightgroup_active_set(view_layer, lightgroup);
2660 viewlayer_lightgroup_make_name_unique(view_layer, lightgroup);
2661 return lightgroup;
2662}
2663
2665{
2666 BLI_assert(BLI_findindex(&view_layer->lightgroups, lightgroup) != -1);
2667 BLI_assert(lightgroup != nullptr);
2668 if (view_layer->active_lightgroup == lightgroup) {
2669 if (lightgroup->next) {
2670 viewlayer_lightgroup_active_set(view_layer, lightgroup->next);
2671 }
2672 else {
2673 viewlayer_lightgroup_active_set(view_layer, lightgroup->prev);
2674 }
2675 }
2676 BLI_freelinkN(&view_layer->lightgroups, lightgroup);
2677}
2678
2680{
2681 viewlayer_lightgroup_active_set(view_layer, lightgroup);
2682}
2683
2685{
2686 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
2687 if (BLI_findindex(&view_layer->lightgroups, lightgroup) != -1) {
2688 return view_layer;
2689 }
2690 }
2691 return nullptr;
2692}
2693
2695 ViewLayer *view_layer,
2696 ViewLayerLightgroup *lightgroup,
2697 const char *name)
2698{
2699 char old_name[64];
2700 STRNCPY_UTF8(old_name, lightgroup->name);
2701 STRNCPY_UTF8(lightgroup->name, name);
2702 viewlayer_lightgroup_make_name_unique(view_layer, lightgroup);
2703
2704 if (scene != nullptr) {
2705 /* Update objects in the scene to refer to the new name instead. */
2706 FOREACH_SCENE_OBJECT_BEGIN (scene, ob) {
2707 if (ID_IS_EDITABLE(ob) && ob->lightgroup != nullptr) {
2708 LightgroupMembership *lgm = ob->lightgroup;
2709 if (STREQ(lgm->name, old_name)) {
2710 STRNCPY_UTF8(lgm->name, lightgroup->name);
2711 }
2712 }
2713 }
2715
2716 /* Update the scene's world to refer to the new name instead. */
2717 if (scene->world != nullptr && ID_IS_EDITABLE(scene->world) &&
2718 scene->world->lightgroup != nullptr)
2719 {
2720 LightgroupMembership *lgm = scene->world->lightgroup;
2721 if (STREQ(lgm->name, old_name)) {
2722 STRNCPY_UTF8(lgm->name, lightgroup->name);
2723 }
2724 }
2725 }
2726}
2727
2729{
2730 if (lgm == nullptr) {
2731 name[0] = '\0';
2732 return 0;
2733 }
2734 return BLI_strncpy_rlen(name, lgm->name, sizeof(lgm->name));
2735}
2736
2738{
2739 if (lgm == nullptr) {
2740 return 0;
2741 }
2742 return strlen(lgm->name);
2743}
2744
2746{
2747 if (name[0] != '\0') {
2748 if (*lgm == nullptr) {
2749 *lgm = MEM_callocN<LightgroupMembership>(__func__);
2750 }
2751 BLI_strncpy((*lgm)->name, name, sizeof((*lgm)->name));
2752 }
2753 else {
2754 if (*lgm != nullptr) {
2755 MEM_freeN(*lgm);
2756 *lgm = nullptr;
2757 }
2758 }
2759}
2760
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:855
void IDP_BlendWrite(BlendWriter *writer, const IDProperty *prop)
Definition idprop.cc:1453
void IDP_FreeProperty_ex(IDProperty *prop, bool do_id_user)
Definition idprop.cc:1237
@ 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:353
@ LIB_ID_CREATE_NO_USER_REFCOUNT
void id_lib_indirect_weak_link(ID *id)
Definition lib_id.cc:298
#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 * 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
@ BLI_MEMPOOL_NOP
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:688
char char size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) 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_INFO(clg_ref, level,...)
Definition CLG_log.h:179
#define CLOG_FATAL(clg_ref,...)
Definition CLG_log.h:183
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:1026
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1012
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_RENDER
@ COLLECTION_HIDE_SELECT
@ COLLECTION_IS_MASTER
@ COLLECTION_HIDE_VIEWPORT
@ VIEW_LAYER_CRYPTOMATTE_ACCURATE
@ 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_HIDE
@ LAYER_COLLECTION_EXCLUDE
@ LAYER_COLLECTION_INDIRECT_ONLY
@ LAYER_COLLECTION_PREVIOUSLY_EXCLUDED
@ LAYER_COLLECTION_HOLDOUT
@ VIEW_LAYER_HAS_EXPORT_COLLECTIONS
@ VIEW_LAYER_FREESTYLE
@ VIEW_LAYER_RENDER
@ VIEW_LAYER_OUT_OF_SYNC
@ AOV_TYPE_COLOR
@ LAYER_COLLECTION_VISIBLE_VIEW_LAYER
@ LAYER_COLLECTION_HIDE_VIEWPORT
@ LAYER_COLLECTION_HAS_OBJECTS
@ AOV_CONFLICT
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)
@ SCE_LAY_FLAG_DEFAULT
#define BASE_SELECTABLE(v3d, base)
@ SCE_PASS_COMBINED
#define BASE_VISIBLE(v3d, base)
@ SPACE_VIEW3D
@ V3D_LOCAL_COLLECTIONS
Read Guarded memory(de)allocation.
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
#define MEM_SAFE_FREE(v)
#define ID_IS_LINKED(_id)
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
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(severity)
Definition log.h:32
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
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
Collection_Runtime runtime
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
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:245
ListBase wm
Definition BKE_main.hh:276
ListBase screens
Definition BKE_main.hh:261
ListBase collections
Definition BKE_main.hh:267
short base_flag
ObjectRuntimeHandle * runtime
short visibility_flag
unsigned short base_local_view_bits
struct bNodeTree * nodetree
struct Collection * master_collection
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
short cryptomatte_flag
ListBase lightgroups
struct IDProperty * id_properties
short cryptomatte_levels
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
float pass_alpha_threshold
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:139