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