Blender V5.0
outliner_collections.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#include <cstring>
10
11#include "BLI_listbase.h"
12#include "BLI_set.hh"
13#include "BLI_utildefines.h"
14
15#include "DNA_ID.h"
17#include "DNA_object_types.h"
18
19#include "BKE_collection.hh"
20#include "BKE_context.hh"
21#include "BKE_layer.hh"
22#include "BKE_lib_id.hh"
23#include "BKE_library.hh"
24#include "BKE_main.hh"
25#include "BKE_report.hh"
26
27#include "DEG_depsgraph.hh"
29
30#include "ED_object.hh"
31#include "ED_outliner.hh"
32#include "ED_screen.hh"
33
34#include "WM_api.hh"
35#include "WM_message.hh"
36#include "WM_types.hh"
37
38#include "RNA_access.hh"
39#include "RNA_define.hh"
40#include "RNA_enum_types.hh"
41
42#include "outliner_intern.hh" /* own include */
43
45
46/* -------------------------------------------------------------------- */
49
51{
52 TreeStoreElem *tselem = TREESTORE(te);
53
54 if (!tselem) {
55 return false;
56 }
57
58 if (ELEM(
60 {
61 return true;
62 }
63 if ((tselem->type == TSE_SOME_ID) && te->idcode == ID_GR) {
64 return true;
65 }
66
67 return false;
68}
69
71{
72 TreeStoreElem *tselem = TREESTORE(te);
73
74 if (!tselem) {
75 return nullptr;
76 }
77
78 if (tselem->type == TSE_LAYER_COLLECTION) {
79 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
80 return lc->collection;
81 }
83 Scene *scene = (Scene *)tselem->id;
84 return scene->master_collection;
85 }
86 if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_GR)) {
87 return (Collection *)tselem->id;
88 }
89
90 return nullptr;
91}
92
94{
95 IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata);
96 TreeStoreElem *tselem = TREESTORE(te);
97
99 BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
100 return TRAVERSE_CONTINUE;
101 }
102
103 if ((tselem->type != TSE_SOME_ID) || (tselem->id && GS(tselem->id->name) != ID_GR)) {
105 }
106
107 return TRAVERSE_CONTINUE;
108}
109
111 void *customdata)
112{
113 IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata);
114 /* If collection is already selected, skip iterating their children. */
117 return TRAVERSE_CONTINUE;
118 }
119 BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
121 }
122 return TRAVERSE_CONTINUE;
123}
124
126{
127 IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata);
128 TreeStoreElem *tselem = TREESTORE(te);
129
131 return TRAVERSE_CONTINUE;
132 }
133
134 if ((tselem->type != TSE_SOME_ID) || (tselem->id == nullptr) || (GS(tselem->id->name) != ID_OB))
135 {
137 }
138
139 BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
140
141 return TRAVERSE_CONTINUE;
142}
143
144} // namespace blender::ed::outliner
145
147{
148 using namespace blender::ed::outliner;
149
150 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
151 IDsSelectedData data = {{nullptr}};
152 outliner_tree_traverse(space_outliner,
153 &space_outliner->tree,
154 0,
157 &data);
158 LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
159 TreeElement *ten_selected = (TreeElement *)link->data;
160 Object *ob = (Object *)TREESTORE(ten_selected)->id;
161 BLI_addtail(objects, BLI_genericNodeN(ob));
162 }
163 BLI_freelistN(&data.selected_array);
164}
165
166namespace blender::ed::outliner {
167
169
170/* -------------------------------------------------------------------- */
173
174} // namespace blender::ed::outliner
175
177{
178 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
179 return (space_outliner != nullptr) &&
181}
182
183namespace blender::ed::outliner {
184
186{
187 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
188 return (space_outliner != nullptr) && (space_outliner->outlinevis == SO_VIEW_LAYER);
189}
190
192{
194 return false;
195 }
196 Scene *scene = CTX_data_scene(C);
197 if (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) {
198 return false;
199 }
200 return true;
201}
202
204{
206 return false;
207 }
209 return false;
210 }
211 return true;
212}
213
215
216/* -------------------------------------------------------------------- */
219
224
226{
227 CollectionNewData *data = static_cast<CollectionNewData *>(customdata);
229
230 if (!collection) {
232 }
233
234 if (data->collection != nullptr) {
235 data->error = true;
236 return TRAVERSE_BREAK;
237 }
238
239 data->collection = collection;
240 return TRAVERSE_CONTINUE;
241}
242
244{
245 WorkSpace *workspace = CTX_wm_workspace(C);
246 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
247 ARegion *region = CTX_wm_region(C);
248 Main *bmain = CTX_data_main(C);
249 Scene *scene = CTX_data_scene(C);
250 ViewLayer *view_layer = CTX_data_view_layer(C);
251
253
254 if (RNA_boolean_get(op->ptr, "nested")) {
255 outliner_build_tree(bmain, workspace, scene, view_layer, space_outliner, region);
256
257 outliner_tree_traverse(space_outliner,
258 &space_outliner->tree,
259 0,
262 &data);
263
264 if (data.error) {
265 BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
266 return OPERATOR_CANCELLED;
267 }
268 }
269
270 if (data.collection == nullptr || !ID_IS_EDITABLE(data.collection) ||
271 ID_IS_OVERRIDE_LIBRARY(data.collection))
272 {
273 data.collection = scene->master_collection;
274 }
275
276 if (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) {
277 BKE_report(op->reports, RPT_ERROR, "Cannot add a new collection to linked/override scene");
278 return OPERATOR_CANCELLED;
279 }
280
281 BKE_collection_add(bmain, data.collection, nullptr);
282
285
286 outliner_cleanup_tree(space_outliner);
288 return OPERATOR_FINISHED;
289}
290
292{
293 /* identifiers */
294 ot->name = "New Collection";
295 ot->idname = "OUTLINER_OT_collection_new";
296 ot->description = "Add a new collection inside selected collection";
297
298 /* API callbacks. */
299 ot->exec = collection_new_exec;
300 ot->poll = collection_new_poll;
301
302 /* flags */
304
305 /* properties */
307 ot->srna, "nested", true, "Nested", "Add as child of selected collection");
309}
310
312
313/* -------------------------------------------------------------------- */
316
322
323 /* Whether the processed operation should be allowed on liboverride collections, or not. */
325 /* Whether the processed operation should be allowed on hierarchy roots of liboverride
326 * collections, or not. */
328 /* When true, do not skip the hierarchy of children when a parent collection is selected. This is
329 * useful for deleting selected child collections, see: #126860. */
330 bool is_recursive = false;
331};
332
334{
335 CollectionEditData *data = static_cast<CollectionEditData *>(customdata);
337
338 if (!collection) {
340 }
341
342 if (collection->flag & COLLECTION_IS_MASTER) {
343 /* Skip - showing warning/error message might be misleading
344 * when deleting multiple collections, so just do nothing. */
345 return TRAVERSE_CONTINUE;
346 }
347
348 if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
350 if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) {
352 }
353 }
354 else {
355 if (!data->is_liboverride_allowed) {
357 }
358 }
359 }
360
361 /* Delete, duplicate and link don't edit children, those will come along
362 * with the parents. */
363 data->collections_to_edit.add(collection);
364 return data->is_recursive ? TRAVERSE_CONTINUE : TRAVERSE_SKIP_CHILDS;
365}
366
368 bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
369{
370 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
371
373 data.scene = scene;
374 data.space_outliner = space_outliner;
375 data.is_liboverride_allowed = false;
376 data.is_liboverride_hierarchy_root_allowed = do_hierarchy;
377 data.is_recursive = !do_hierarchy;
378
379 /* We first walk over and find the Collections we actually want to delete
380 * (ignoring duplicates). */
381 outliner_tree_traverse(space_outliner,
382 &space_outliner->tree,
383 0,
386 &data);
387
388 /* Effectively delete the collections. */
389 for (Collection *collection : data.collections_to_edit) {
390 /* Test in case collection got deleted as part of another one. */
391 if (BLI_findindex(&bmain->collections, collection) != -1) {
392 /* We cannot allow deleting collections that are indirectly linked,
393 * or that are used by (linked to...) other linked scene/collection. */
394 bool skip = false;
395 if (!ID_IS_EDITABLE(collection)) {
396 if (collection->id.tag & ID_TAG_INDIRECT) {
397 skip = true;
398 }
399 else {
400 LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime->parents) {
401 Collection *parent = cparent->collection;
402 if (!ID_IS_EDITABLE(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) {
403 skip = true;
404 break;
405 }
406 if (parent->flag & COLLECTION_IS_MASTER) {
408
409 ID *scene_owner = BKE_id_owner_get(&parent->id);
410 BLI_assert(scene_owner != nullptr);
411 BLI_assert(GS(scene_owner->name) == ID_SCE);
412 if (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
413 skip = true;
414 break;
415 }
416 }
417 }
418 }
419 }
420
421 if (!skip) {
422 BKE_collection_delete(bmain, collection, do_hierarchy);
423 }
424 else {
425 BKE_reportf(reports,
427 "Cannot delete collection '%s', it is either a linked one used by other "
428 "linked scenes/collections, or a library override one",
429 collection->id.name + 2);
430 }
431 }
432 }
433}
434
436{
437 Main *bmain = CTX_data_main(C);
438 Scene *scene = CTX_data_scene(C);
439 ViewLayer *view_layer = CTX_data_view_layer(C);
441 BKE_view_layer_synced_ensure(scene, view_layer);
442 const Base *basact_prev = BKE_view_layer_active_base_get(view_layer);
443
444 outliner_collection_delete(C, bmain, scene, op->reports, true);
445
448
450
451 BKE_view_layer_synced_ensure(scene, view_layer);
452 if (basact_prev != BKE_view_layer_active_base_get(view_layer)) {
453 WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
454 }
455
457
458 return OPERATOR_FINISHED;
459}
460
462{
463 /* identifiers */
464 ot->name = "Delete Hierarchy";
465 ot->idname = "OUTLINER_OT_collection_hierarchy_delete";
466 ot->description = "Delete selected collection hierarchies";
467
468 /* API callbacks. */
471
472 /* flags */
474}
475
477
478/* -------------------------------------------------------------------- */
481
486
488 void *customdata)
489{
491 TreeStoreElem *tselem = TREESTORE(te);
492
493 switch (tselem->type) {
495 data->layer_collection = static_cast<LayerCollection *>(te->directdata);
496 return TRAVERSE_BREAK;
497 case TSE_R_LAYER:
500 return TRAVERSE_CONTINUE;
501 default:
503 }
504}
505
507{
508 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
509
511
512 outliner_tree_traverse(space_outliner,
513 &space_outliner->tree,
514 0,
517 &data);
518 return data.layer_collection;
519}
520
522{
523 Scene *scene = CTX_data_scene(C);
524 ViewLayer *view_layer = CTX_data_view_layer(C);
525 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
526 bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
527
528 IDsSelectedData selected_collections{};
529 outliner_tree_traverse(space_outliner,
530 &space_outliner->tree,
531 0,
534 &selected_collections);
535
536 if (selected_collections.selected_array.first == nullptr) {
537 return OPERATOR_CANCELLED;
538 }
539
540 LISTBASE_FOREACH (LinkData *, link, &selected_collections.selected_array) {
541 TreeElement *te = static_cast<TreeElement *>(link->data);
543 LayerCollection *layer_collection = static_cast<LayerCollection *>(te->directdata);
544 BKE_layer_collection_objects_select(scene, view_layer, layer_collection, deselect);
545 }
546 }
547
548 BLI_freelistN(&selected_collections.selected_array);
552
553 return OPERATOR_FINISHED;
554}
555
557{
558 /* identifiers */
559 ot->name = "Select Objects";
560 ot->idname = "OUTLINER_OT_collection_objects_select";
561 ot->description = "Select objects in collection";
562
563 /* API callbacks. */
566
567 /* flags */
569}
570
572{
573 /* identifiers */
574 ot->name = "Deselect Objects";
575 ot->idname = "OUTLINER_OT_collection_objects_deselect";
576 ot->description = "Deselect objects in collection";
577
578 /* API callbacks. */
581
582 /* flags */
584}
585
587
588/* -------------------------------------------------------------------- */
591
595
597 void *customdata)
598{
599 CollectionDuplicateData *data = static_cast<CollectionDuplicateData *>(customdata);
600 TreeStoreElem *tselem = TREESTORE(te);
601
602 switch (tselem->type) {
604 data->te = te;
605 return TRAVERSE_BREAK;
606 case TSE_R_LAYER:
609 default:
610 return TRAVERSE_CONTINUE;
611 }
612}
613
615{
616 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
617
619
620 outliner_tree_traverse(space_outliner,
621 &space_outliner->tree,
622 0,
625 &data);
626 return data.te;
627}
628
630{
631 Main *bmain = CTX_data_main(C);
632 const bool linked = strstr(op->idname, "linked") != nullptr;
633 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
634
635 IDsSelectedData selected_collections{};
636 outliner_tree_traverse(space_outliner,
637 &space_outliner->tree,
638 0,
641 &selected_collections);
642
643 /* Can happen when calling from a key binding. */
644 if (BLI_listbase_is_empty(&selected_collections.selected_array)) {
645 BKE_report(op->reports, RPT_ERROR, "No active collection");
646 return OPERATOR_CANCELLED;
647 }
648
649 int failed_count = 0;
650 LISTBASE_FOREACH (LinkData *, link, &selected_collections.selected_array) {
651 TreeElement *te = static_cast<TreeElement *>(link->data);
654 nullptr;
655 if (!parent) {
656 failed_count += 1;
657 continue;
658 }
659 CollectionChild *child = BKE_collection_child_find(parent, collection);
660
661 /* We are allowed to duplicated linked collections (they will become local IDs then),
662 * but we should not allow its parent to be a linked ID, ever.
663 * This can happen when a whole scene is linked e.g. */
664 if (parent != nullptr && (!ID_IS_EDITABLE(parent) || ID_IS_OVERRIDE_LIBRARY(parent))) {
665 Scene *scene = CTX_data_scene(C);
666 parent = (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) ?
667 nullptr :
668 scene->master_collection;
669 }
670 else if (parent != nullptr && (parent->flag & COLLECTION_IS_MASTER) != 0) {
672
673 Scene *scene_owner = reinterpret_cast<Scene *>(BKE_id_owner_get(&parent->id));
674 BLI_assert(scene_owner != nullptr);
675 BLI_assert(GS(scene_owner->id.name) == ID_SCE);
676
677 if (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
678 scene_owner = CTX_data_scene(C);
679 parent = (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) ?
680 nullptr :
681 scene_owner->master_collection;
682 }
683 }
684
685 const eDupli_ID_Flags dupli_flags = (eDupli_ID_Flags)(USER_DUP_OBJECT |
686 (linked ? 0 : U.dupflag));
688 bmain, parent, child, collection, dupli_flags, LIB_ID_DUPLICATE_IS_ROOT_ID);
689 }
690
691 if (failed_count != 0) {
694 "Unable to duplicate %d of the selected collections. "
695 "Could not find a valid parent collection for the new duplicate, "
696 "they won't be linked to any view layer",
697 failed_count);
698 }
699
700 BLI_freelistN(&selected_collections.selected_array);
704
705 return OPERATOR_FINISHED;
706}
707
709{
710 /* identifiers */
711 ot->name = "Duplicate Linked Collection";
712 ot->idname = "OUTLINER_OT_collection_duplicate_linked";
713 ot->description =
714 "Recursively duplicate the collection, all its children and objects, with linked object "
715 "data";
716
717 /* API callbacks. */
720
721 /* flags */
723}
724
726{
727 /* identifiers */
728 ot->name = "Duplicate Collection";
729 ot->idname = "OUTLINER_OT_collection_duplicate";
730 ot->description =
731 "Recursively duplicate the collection, all its children, objects and object data";
732
733 /* API callbacks. */
736
737 /* flags */
739}
740
742
743/* -------------------------------------------------------------------- */
746
748{
749 Main *bmain = CTX_data_main(C);
750 Scene *scene = CTX_data_scene(C);
751 Collection *active_collection = CTX_data_layer_collection(C)->collection;
752 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
753
755 data.scene = scene;
756 data.space_outliner = space_outliner;
757 data.is_liboverride_allowed = false; /* No linking of non-root collections. */
758 data.is_liboverride_hierarchy_root_allowed = true;
759
760 if ((!ID_IS_EDITABLE(active_collection) || ID_IS_OVERRIDE_LIBRARY(active_collection)) ||
761 ((active_collection->flag & COLLECTION_IS_MASTER) &&
762 (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene))))
763 {
765 op->reports, RPT_ERROR, "Cannot add a collection to a linked/override collection/scene");
766 return OPERATOR_CANCELLED;
767 }
768
769 /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */
770 outliner_tree_traverse(space_outliner,
771 &space_outliner->tree,
772 0,
775 &data);
776
777 /* Effectively link the collections. */
778 for (Collection *collection : data.collections_to_edit) {
779 BKE_collection_child_add(bmain, active_collection, collection);
780 id_fake_user_clear(&collection->id);
781 }
782
783 DEG_id_tag_update(&active_collection->id, ID_RECALC_SYNC_TO_EVAL);
785
787
788 return OPERATOR_FINISHED;
789}
790
792{
793 /* identifiers */
794 ot->name = "Link Collection";
795 ot->idname = "OUTLINER_OT_collection_link";
796 ot->description = "Link selected collections to active scene";
797
798 /* API callbacks. */
799 ot->exec = collection_link_exec;
801
802 /* flags */
804}
805
807
808/* -------------------------------------------------------------------- */
811
813{
814 Main *bmain = CTX_data_main(C);
815 Scene *scene = CTX_data_scene(C);
816 ViewLayer *view_layer = CTX_data_view_layer(C);
817 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
819 data.scene = scene;
820 data.space_outliner = space_outliner;
821 data.is_liboverride_allowed = true;
822 data.is_liboverride_hierarchy_root_allowed = true;
823
824 /* We first walk over and find the Collections we actually want to instance
825 * (ignoring duplicates). */
826 outliner_tree_traverse(space_outliner,
827 &space_outliner->tree,
828 0,
831 &data);
832
833 /* Find an active collection to add to, that doesn't give dependency cycles. */
834 LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
835
836 for (Collection *collection : data.collections_to_edit) {
837 while (BKE_collection_cycle_find(active_lc->collection, collection)) {
838 active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
839 }
840 }
841
842 /* Effectively instance the collections. */
843 for (Collection *collection : data.collections_to_edit) {
845 C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, nullptr, false, 0);
846 ob->instance_collection = collection;
848 id_us_plus(&collection->id);
849 }
850
852
854
855 return OPERATOR_FINISHED;
856}
857
859{
860 /* identifiers */
861 ot->name = "Instance Collection";
862 ot->idname = "OUTLINER_OT_collection_instance";
863 ot->description = "Instance selected collections to active scene";
864
865 /* API callbacks. */
868
869 /* flags */
871}
872
874
875/* -------------------------------------------------------------------- */
878
880{
881 CollectionEditData *data = static_cast<CollectionEditData *>(customdata);
882 TreeStoreElem *tselem = TREESTORE(te);
883
884 if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
885 return TRAVERSE_CONTINUE;
886 }
887
888 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
889
891 /* skip - showing warning/error message might be misleading
892 * when deleting multiple collections, so just do nothing */
893 }
894 else {
895 /* Delete, duplicate and link don't edit children, those will come along
896 * with the parents. */
897 data->layer_collections_to_edit.add(lc);
898 }
899
900 return TRAVERSE_CONTINUE;
901}
902
904{
905 /* Poll function so the right click menu show current state of selected collections. */
906 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
907 if (!(space_outliner && space_outliner->outlinevis == SO_VIEW_LAYER)) {
908 return false;
909 }
910
911 Scene *scene = CTX_data_scene(C);
913 data.scene = scene;
914 data.space_outliner = space_outliner;
915 data.is_liboverride_allowed = true;
916 data.is_liboverride_hierarchy_root_allowed = true;
917 bool result = false;
918
919 outliner_tree_traverse(space_outliner,
920 &space_outliner->tree,
921 0,
924 &data);
925
926 for (LayerCollection *lc : data.layer_collections_to_edit) {
927 if (clear && (lc->flag & flag)) {
928 result = true;
929 }
930 else if (!clear && !(lc->flag & flag)) {
931 result = true;
932 }
933 }
934
935 return result;
936}
937
942
947
952
957
962
967
969{
970 Main *bmain = CTX_data_main(C);
971 Scene *scene = CTX_data_scene(C);
972 ViewLayer *view_layer = CTX_data_view_layer(C);
973 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
975 data.scene = scene;
976 data.space_outliner = space_outliner;
977 data.is_liboverride_allowed = true;
978 data.is_liboverride_hierarchy_root_allowed = true;
979 bool clear = strstr(op->idname, "clear") != nullptr;
980 int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
981 strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
983
984 outliner_tree_traverse(space_outliner,
985 &space_outliner->tree,
986 0,
989 &data);
990
991 for (LayerCollection *lc : data.layer_collections_to_edit) {
993 }
994
997
999
1000 return OPERATOR_FINISHED;
1001}
1002
1004{
1005 /* identifiers */
1006 ot->name = "Disable from View Layer";
1007 ot->idname = "OUTLINER_OT_collection_exclude_set";
1008 ot->description = "Exclude collection from the active view layer";
1009
1010 /* API callbacks. */
1013
1014 /* flags */
1015 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1016}
1017
1019{
1020 /* identifiers */
1021 ot->name = "Enable in View Layer";
1022 ot->idname = "OUTLINER_OT_collection_exclude_clear";
1023 ot->description = "Include collection in the active view layer";
1024
1025 /* API callbacks. */
1028
1029 /* flags */
1030 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1031}
1032
1034{
1035 /* identifiers */
1036 ot->name = "Set Holdout";
1037 ot->idname = "OUTLINER_OT_collection_holdout_set";
1038 ot->description = "Mask collection in the active view layer";
1039
1040 /* API callbacks. */
1043
1044 /* flags */
1045 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1046}
1047
1049{
1050 /* identifiers */
1051 ot->name = "Clear Holdout";
1052 ot->idname = "OUTLINER_OT_collection_holdout_clear";
1053 ot->description = "Clear masking of collection in the active view layer";
1054
1055 /* API callbacks. */
1058
1059 /* flags */
1060 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1061}
1062
1064{
1065 /* identifiers */
1066 ot->name = "Set Indirect Only";
1067 ot->idname = "OUTLINER_OT_collection_indirect_only_set";
1068 ot->description =
1069 "Set collection to only contribute indirectly (through shadows and reflections) in the view "
1070 "layer";
1071
1072 /* API callbacks. */
1075
1076 /* flags */
1077 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1078}
1079
1081{
1082 /* identifiers */
1083 ot->name = "Clear Indirect Only";
1084 ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
1085 ot->description = "Clear collection contributing only indirectly in the view layer";
1086
1087 /* API callbacks. */
1090
1091 /* flags */
1092 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1093}
1094
1096
1097/* -------------------------------------------------------------------- */
1100
1102{
1103 Scene *scene = CTX_data_scene(C);
1104 ViewLayer *view_layer = CTX_data_view_layer(C);
1105 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1106 const bool extend = RNA_boolean_get(op->ptr, "extend");
1108 data.scene = scene;
1109 data.space_outliner = space_outliner;
1110 data.is_liboverride_allowed = true;
1111 data.is_liboverride_hierarchy_root_allowed = true;
1112 outliner_tree_traverse(space_outliner,
1113 &space_outliner->tree,
1114 0,
1117 &data);
1118
1119 for (LayerCollection *layer_collection : data.layer_collections_to_edit) {
1120 if (extend) {
1121 BKE_layer_collection_isolate_global(scene, view_layer, layer_collection, true);
1122 }
1123 else {
1124 PropertyRNA *prop = RNA_struct_type_find_property(&RNA_LayerCollection, "hide_viewport");
1126 &scene->id, &RNA_LayerCollection, layer_collection);
1127
1128 /* We need to flip the value because the isolate flag routine was designed to work from the
1129 * outliner as a callback. That means the collection visibility was set before the callback
1130 * was called. */
1131 const bool value = !RNA_property_boolean_get(&ptr, prop);
1133 scene, view_layer, layer_collection, nullptr, prop, "hide_viewport", value);
1134 break;
1135 }
1136 }
1137
1140
1142 return OPERATOR_FINISHED;
1143}
1144
1146 wmOperator *op,
1147 const wmEvent *event)
1148{
1149 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
1150 if (!RNA_property_is_set(op->ptr, prop) && (event->modifier & KM_SHIFT)) {
1151 RNA_property_boolean_set(op->ptr, prop, true);
1152 }
1153 return collection_isolate_exec(C, op);
1154}
1155
1157{
1158 /* identifiers */
1159 ot->name = "Isolate Collection";
1160 ot->idname = "OUTLINER_OT_collection_isolate";
1161 ot->description = "Hide all but this collection and its parents";
1162
1163 /* API callbacks. */
1165 ot->invoke = collection_isolate_invoke;
1167
1168 /* flags */
1169 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1170
1171 /* properties */
1173 ot->srna, "extend", false, "Extend", "Extend current visible collections");
1175}
1176
1181
1186
1188{
1190 return false;
1191 }
1192 return outliner_active_layer_collection(C) != nullptr;
1193}
1194
1196{
1197 Scene *scene = CTX_data_scene(C);
1198 ViewLayer *view_layer = CTX_data_view_layer(C);
1199 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1200 const bool is_inside = strstr(op->idname, "inside") != nullptr;
1201 const bool show = strstr(op->idname, "show") != nullptr;
1203 data.scene = scene;
1204 data.space_outliner = space_outliner;
1205 data.is_liboverride_allowed = true;
1206 data.is_liboverride_hierarchy_root_allowed = true;
1207
1208 outliner_tree_traverse(space_outliner,
1209 &space_outliner->tree,
1210 0,
1213 &data);
1214
1215 for (LayerCollection *layer_collection : data.layer_collections_to_edit) {
1216 BKE_layer_collection_set_visible(scene, view_layer, layer_collection, show, is_inside);
1217 }
1218
1221
1223 return OPERATOR_FINISHED;
1224}
1225
1227{
1228 /* identifiers */
1229 ot->name = "Show Collection";
1230 ot->idname = "OUTLINER_OT_collection_show";
1231 ot->description = "Show the collection in this view layer";
1232
1233 /* API callbacks. */
1235 ot->poll = collection_show_poll;
1236
1237 /* flags */
1238 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1239}
1240
1242{
1243 /* identifiers */
1244 ot->name = "Hide Collection";
1245 ot->idname = "OUTLINER_OT_collection_hide";
1246 ot->description = "Hide the collection in this view layer";
1247
1248 /* API callbacks. */
1250 ot->poll = collection_hide_poll;
1251
1252 /* flags */
1253 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1254}
1255
1257{
1258 /* identifiers */
1259 ot->name = "Show Inside Collection";
1260 ot->idname = "OUTLINER_OT_collection_show_inside";
1261 ot->description = "Show all the objects and collections inside the collection";
1262
1263 /* API callbacks. */
1265 ot->poll = collection_inside_poll;
1266
1267 /* flags */
1268 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1269}
1270
1272{
1273 /* identifiers */
1274 ot->name = "Hide Inside Collection";
1275 ot->idname = "OUTLINER_OT_collection_hide_inside";
1276 ot->description = "Hide all the objects and collections inside the collection";
1277
1278 /* API callbacks. */
1280 ot->poll = collection_inside_poll;
1281
1282 /* flags */
1283 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1284}
1285
1287
1288/* -------------------------------------------------------------------- */
1291
1292static bool collection_flag_poll(bContext *C, bool clear, int flag)
1293{
1295 return false;
1296 }
1297
1299 if (te == nullptr) {
1300 return false;
1301 }
1302
1304 if (collection == nullptr) {
1305 return false;
1306 }
1307
1308 if (clear && (collection->flag & flag)) {
1309 return true;
1310 }
1311 if (!clear && !(collection->flag & flag)) {
1312 return true;
1313 }
1314
1315 return false;
1316}
1317
1322
1327
1332
1337
1339{
1340 Main *bmain = CTX_data_main(C);
1341 Scene *scene = CTX_data_scene(C);
1342 ViewLayer *view_layer = CTX_data_view_layer(C);
1343 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1344 const bool is_render = strstr(op->idname, "render");
1345 const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
1348 data.scene = scene;
1349 data.space_outliner = space_outliner;
1350 data.is_liboverride_allowed = true;
1351 data.is_liboverride_hierarchy_root_allowed = true;
1352 const bool has_layer_collection = space_outliner->outlinevis == SO_VIEW_LAYER;
1353
1354 if (has_layer_collection) {
1355 outliner_tree_traverse(space_outliner,
1356 &space_outliner->tree,
1357 0,
1360 &data);
1361 for (LayerCollection *layer_collection : data.layer_collections_to_edit) {
1362 Collection *collection = layer_collection->collection;
1363 if (!BKE_id_is_editable(bmain, &collection->id)) {
1364 continue;
1365 }
1366 if (clear) {
1367 collection->flag &= ~flag;
1368 }
1369 else {
1370 collection->flag |= flag;
1371 }
1372
1373 /* Make sure (at least for this view layer) the collection is visible. */
1374 if (clear && !is_render) {
1375 layer_collection->flag &= ~LAYER_COLLECTION_HIDE;
1376 }
1377 }
1378 }
1379 else {
1380 outliner_tree_traverse(space_outliner,
1381 &space_outliner->tree,
1382 0,
1385 &data);
1386 for (Collection *collection : data.collections_to_edit) {
1387 if (!BKE_id_is_editable(bmain, &collection->id)) {
1388 continue;
1389 }
1390
1391 if (clear) {
1392 collection->flag &= ~flag;
1393 }
1394 else {
1395 collection->flag |= flag;
1396 }
1397 }
1398 }
1399
1402
1403 if (!is_render) {
1405 }
1406
1408 return OPERATOR_FINISHED;
1409}
1410
1412{
1413 /* identifiers */
1414 ot->name = "Enable Collection";
1415 ot->idname = "OUTLINER_OT_collection_enable";
1416 ot->description = "Enable viewport display in the view layers";
1417
1418 /* API callbacks. */
1419 ot->exec = collection_flag_exec;
1420 ot->poll = collection_enable_poll;
1421
1422 /* flags */
1423 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1424}
1425
1427{
1428 /* identifiers */
1429 ot->name = "Disable Collection";
1430 ot->idname = "OUTLINER_OT_collection_disable";
1431 ot->description = "Disable viewport display in the view layers";
1432
1433 /* API callbacks. */
1434 ot->exec = collection_flag_exec;
1436
1437 /* flags */
1438 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1439}
1440
1442{
1443 /* identifiers */
1444 ot->name = "Enable Collection in Render";
1445 ot->idname = "OUTLINER_OT_collection_enable_render";
1446 ot->description = "Render the collection";
1447
1448 /* API callbacks. */
1449 ot->exec = collection_flag_exec;
1451
1452 /* flags */
1453 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1454}
1455
1457{
1458 /* identifiers */
1459 ot->name = "Disable Collection in Render";
1460 ot->idname = "OUTLINER_OT_collection_disable_render";
1461 ot->description = "Do not render this collection";
1462
1463 /* API callbacks. */
1464 ot->exec = collection_flag_exec;
1466
1467 /* flags */
1468 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1469}
1470
1478
1480
1481/* -------------------------------------------------------------------- */
1484
1486{
1487 OutlinerHideEditData *data = static_cast<OutlinerHideEditData *>(customdata);
1488 TreeStoreElem *tselem = TREESTORE(te);
1489
1490 if (tselem == nullptr) {
1491 return TRAVERSE_CONTINUE;
1492 }
1493
1494 if (tselem->type == TSE_LAYER_COLLECTION) {
1495 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
1496
1498 /* Skip - showing warning/error message might be misleading
1499 * when deleting multiple collections, so just do nothing. */
1500 }
1501 else {
1502 /* Delete, duplicate and link don't edit children,
1503 * those will come along with the parents. */
1504 data->collections_to_edit.add(lc);
1505 }
1506 }
1507 else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1508 Object *ob = (Object *)tselem->id;
1509 BKE_view_layer_synced_ensure(data->scene, data->view_layer);
1510 Base *base = BKE_view_layer_base_find(data->view_layer, ob);
1511 data->bases_to_edit.add(base);
1512 }
1513
1514 return TRAVERSE_CONTINUE;
1515}
1516
1518{
1519 Scene *scene = CTX_data_scene(C);
1520 ViewLayer *view_layer = CTX_data_view_layer(C);
1521 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1523 data.scene = scene;
1524 data.view_layer = view_layer;
1525 data.space_outliner = space_outliner;
1526
1527 outliner_tree_traverse(space_outliner,
1528 &space_outliner->tree,
1529 0,
1532 &data);
1533
1534 for (LayerCollection *layer_collection : data.collections_to_edit) {
1535 BKE_layer_collection_set_visible(scene, view_layer, layer_collection, false, false);
1536 }
1537
1538 for (Base *base : data.bases_to_edit) {
1539 base->flag |= BASE_HIDDEN;
1540 }
1541
1544
1546 return OPERATOR_FINISHED;
1547}
1548
1550{
1551 /* identifiers */
1552 ot->name = "Hide";
1553 ot->idname = "OUTLINER_OT_hide";
1554 ot->description = "Hide selected objects and collections";
1555
1556 /* API callbacks. */
1557 ot->exec = outliner_hide_exec;
1559
1560 /* flags */
1561 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1562}
1563
1565{
1566 Scene *scene = CTX_data_scene(C);
1567 ViewLayer *view_layer = CTX_data_view_layer(C);
1568
1569 /* Unhide all the collections. */
1570 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1571 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1573 }
1574
1575 /* Unhide all objects. */
1576 BKE_view_layer_synced_ensure(scene, view_layer);
1578 base->flag &= ~BASE_HIDDEN;
1579 }
1580
1583
1585 return OPERATOR_FINISHED;
1586}
1587
1589{
1590 /* identifiers */
1591 ot->name = "Unhide All";
1592 ot->idname = "OUTLINER_OT_unhide_all";
1593 ot->description = "Unhide all objects and collections";
1594
1595 /* API callbacks. */
1598
1599 /* flags */
1600 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1601}
1602
1604
1605/* -------------------------------------------------------------------- */
1608
1610{
1611 Scene *scene = CTX_data_scene(C);
1612 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1613 const short color_tag = RNA_enum_get(op->ptr, "color");
1614
1615 IDsSelectedData selected{};
1616
1617 outliner_tree_traverse(space_outliner,
1618 &space_outliner->tree,
1619 0,
1622 &selected);
1623
1624 LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
1625 TreeElement *te_selected = (TreeElement *)link->data;
1626
1627 Collection *collection = outliner_collection_from_tree_element(te_selected);
1628 if (collection == scene->master_collection) {
1629 continue;
1630 }
1631 if (!BKE_id_is_editable(CTX_data_main(C), &collection->id)) {
1632 BKE_report(op->reports, RPT_WARNING, "Cannot add a color tag to a linked collection");
1633 continue;
1634 }
1635
1636 collection->color_tag = color_tag;
1637 };
1638
1639 BLI_freelistN(&selected.selected_array);
1640
1642
1643 return OPERATOR_FINISHED;
1644}
1645
1647{
1648 /* identifiers */
1649 ot->name = "Set Color Tag";
1650 ot->idname = "OUTLINER_OT_collection_color_tag_set";
1651 ot->description = "Set a color tag for the selected collections";
1652
1653 /* API callbacks. */
1656
1657 /* flags */
1658 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1659
1661 ot->srna, "color", rna_enum_collection_color_items, COLLECTION_COLOR_NONE, "Color Tag", "");
1662}
1663
1665
1666} // namespace blender::ed::outliner
CollectionChild * BKE_collection_child_find(Collection *parent, Collection *collection)
Collection * BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
Collection * BKE_collection_duplicate(Main *bmain, Collection *parent, CollectionChild *child_old, Collection *collection, eDupli_ID_Flags duplicate_flags, uint duplicate_options)
bool BKE_collection_child_add(Main *bmain, Collection *parent, Collection *child)
bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
WorkSpace * CTX_wm_workspace(const bContext *C)
LayerCollection * CTX_data_layer_collection(const bContext *C)
SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
bool BKE_layer_collection_objects_select(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool deselect)
Base * BKE_view_layer_active_base_get(ViewLayer *view_layer)
void BKE_layer_collection_set_visible(const Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool visible, bool hierarchy)
void BKE_layer_collection_isolate_global(Scene *scene, ViewLayer *view_layer, LayerCollection *lc, bool extend)
void BKE_view_layer_need_resync_tag(ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
LayerCollection * BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc)
void BKE_layer_collection_set_flag(LayerCollection *lc, int flag, bool value)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2523
void id_us_plus(ID *id)
Definition lib_id.cc:358
ID * BKE_id_owner_get(ID *id, const bool debug_relationship_assert=true)
Definition lib_id.cc:2511
void id_fake_user_clear(ID *id)
Definition lib_id.cc:404
@ LIB_ID_DUPLICATE_IS_ROOT_ID
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert(a)
Definition BLI_assert.h:46
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:922
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
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
#define ELEM(...)
#define STREQ(a, b)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
ID and Library types, which are fundamental for SDNA.
@ ID_TAG_INDIRECT
Definition DNA_ID.h:848
@ ID_RECALC_SELECT
Definition DNA_ID.h:1101
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1104
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition DNA_ID.h:723
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:705
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
#define ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(_id)
Definition DNA_ID.h:733
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:774
@ ID_SCE
@ ID_GR
@ ID_OB
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_RENDER
@ COLLECTION_IS_MASTER
@ COLLECTION_HIDE_VIEWPORT
@ COLLECTION_COLOR_NONE
@ LAYER_COLLECTION_HIDE
@ LAYER_COLLECTION_EXCLUDE
@ LAYER_COLLECTION_INDIRECT_ONLY
@ LAYER_COLLECTION_HOLDOUT
@ BASE_HIDDEN
Object is a sort of wrapper for general info.
@ OB_EMPTY
@ OB_DUPLICOLLECTION
@ TSE_VIEW_COLLECTION_BASE
@ TSE_SCENE_COLLECTION_BASE
@ TSE_LAYER_COLLECTION
@ TSE_SOME_ID
@ TSE_R_LAYER
@ TSE_SELECTED
@ SO_LIBRARIES
@ SO_VIEW_LAYER
@ SO_SCENES
eDupli_ID_Flags
@ USER_DUP_OBJECT
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_outliner_select_sync_from_object_tag(bContext *C)
bool ED_outliner_collections_editor_poll(bContext *C)
bool ED_operator_region_outliner_active(bContext *C)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
#define C
Definition RandGen.cpp:29
@ KM_SHIFT
Definition WM_types.hh:278
#define ND_OB_SELECT
Definition WM_types.hh:442
#define NC_SCENE
Definition WM_types.hh:378
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define ND_LAYER_CONTENT
Definition WM_types.hh:453
#define ND_LAYER
Definition WM_types.hh:450
#define U
BMesh const char void * data
static bool is_inside(int x, int y, int cols, int rows)
Definition filesel.cc:764
#define GS(x)
#define active
static void clear(Message &msg)
Definition msgfmt.cc:213
Object * add_type(bContext *C, int type, const char *name, const float loc[3], const float rot[3], bool enter_editmode, unsigned short local_view_bits) ATTR_NONNULL(1) ATTR_RETURNS_NONNULL
void OUTLINER_OT_collection_duplicate_linked(wmOperatorType *ot)
void OUTLINER_OT_collection_objects_deselect(wmOperatorType *ot)
void OUTLINER_OT_collection_disable_render(wmOperatorType *ot)
static bool collections_exclude_clear_poll(bContext *C)
void OUTLINER_OT_collection_link(wmOperatorType *ot)
void OUTLINER_OT_collection_color_tag_set(wmOperatorType *ot)
void OUTLINER_OT_collection_hierarchy_delete(wmOperatorType *ot)
void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
static bool collection_inside_poll(bContext *C)
static TreeTraversalAction collection_collect_data_to_edit(TreeElement *te, void *customdata)
void OUTLINER_OT_collection_show(wmOperatorType *ot)
static wmOperatorStatus collection_isolate_exec(bContext *C, wmOperator *op)
static bool collections_holdout_clear_poll(bContext *C)
bool outliner_is_collection_tree_element(const TreeElement *te)
static wmOperatorStatus collection_new_exec(bContext *C, wmOperator *op)
static TreeElement * outliner_active_collection(bContext *C)
static bool collection_disable_poll(bContext *C)
static wmOperatorStatus collection_objects_select_exec(bContext *C, wmOperator *op)
static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata)
static wmOperatorStatus collection_visibility_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
void OUTLINER_OT_hide(wmOperatorType *ot)
static bool collections_exclude_set_poll(bContext *C)
void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot)
static bool collection_show_poll(bContext *C)
void OUTLINER_OT_collection_hide(wmOperatorType *ot)
void outliner_collection_isolate_flag(Scene *scene, ViewLayer *view_layer, LayerCollection *layer_collection, Collection *collection, PropertyRNA *layer_or_collection_prop, const char *propname, const bool value)
void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot)
static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
void OUTLINER_OT_collection_objects_select(wmOperatorType *ot)
static TreeTraversalAction layer_collection_collect_data_to_edit(TreeElement *te, void *customdata)
static LayerCollection * outliner_active_layer_collection(bContext *C)
static wmOperatorStatus collection_instance_exec(bContext *C, wmOperator *)
void outliner_collection_delete(bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
static bool collection_enable_poll(bContext *C)
static bool collections_holdout_set_poll(bContext *C)
static wmOperatorStatus collection_hierarchy_delete_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_unhide_all(wmOperatorType *ot)
void OUTLINER_OT_collection_hide_inside(wmOperatorType *ot)
void OUTLINER_OT_collection_enable(wmOperatorType *ot)
static wmOperatorStatus collection_flag_exec(bContext *C, wmOperator *op)
static bool outliner_view_layer_collections_editor_poll(bContext *C)
static wmOperatorStatus collection_link_exec(bContext *C, wmOperator *op)
TreeTraversalAction outliner_collect_selected_objects(TreeElement *te, void *customdata)
Collection * outliner_collection_from_tree_element(const TreeElement *te)
static bool collections_indirect_only_clear_poll(bContext *C)
static wmOperatorStatus outliner_unhide_all_exec(bContext *C, wmOperator *)
bool outliner_tree_traverse(const SpaceOutliner *space_outliner, ListBase *tree, int filter_te_flag, int filter_tselem_flag, TreeTraversalFunc func, void *customdata)
static bool collections_indirect_only_set_poll(bContext *C)
static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te, void *customdata)
static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void *customdata)
static TreeTraversalAction outliner_hide_collect_data_to_edit(TreeElement *te, void *customdata)
static bool collection_disable_render_poll(bContext *C)
void outliner_cleanup_tree(SpaceOutliner *space_outliner)
static bool collection_edit_in_active_scene_poll(bContext *C)
void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot)
void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
static bool collection_hide_poll(bContext *C)
void OUTLINER_OT_collection_isolate(wmOperatorType *ot)
void OUTLINER_OT_collection_disable(wmOperatorType *ot)
void OUTLINER_OT_collection_show_inside(wmOperatorType *ot)
static wmOperatorStatus outliner_color_tag_set_exec(bContext *C, wmOperator *op)
static wmOperatorStatus collection_duplicate_exec(bContext *C, wmOperator *op)
static TreeTraversalAction outliner_collect_selected_parent_collections(TreeElement *te, void *customdata)
static wmOperatorStatus outliner_hide_exec(bContext *C, wmOperator *)
static bool collection_flag_poll(bContext *C, bool clear, int flag)
void outliner_build_tree(Main *mainvar, WorkSpace *workspace, Scene *scene, ViewLayer *view_layer, SpaceOutliner *space_outliner, ARegion *region)
static bool collection_enable_render_poll(bContext *C)
void OUTLINER_OT_collection_new(wmOperatorType *ot)
static bool collection_new_poll(bContext *C)
void OUTLINER_OT_collection_instance(wmOperatorType *ot)
void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot)
TreeTraversalAction outliner_collect_selected_collections(TreeElement *te, void *customdata)
static wmOperatorStatus collection_view_layer_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_enable_render(wmOperatorType *ot)
static wmOperatorStatus collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
bool ED_outliner_collections_editor_poll(bContext *C)
#define TREESTORE(a)
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
int RNA_enum_get(PointerRNA *ptr, const char *name)
const EnumPropertyItem rna_enum_collection_color_items[]
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
short flag
CollectionRuntimeHandle * runtime
Definition DNA_ID.h:414
int tag
Definition DNA_ID.h:442
char name[258]
Definition DNA_ID.h:432
short flag
Definition DNA_ID.h:438
ListBase layer_collections
struct Collection * collection
void * first
ListBase collections
Definition BKE_main.hh:298
short transflag
struct Collection * instance_collection
struct Collection * master_collection
View3DCursor cursor
ListBase layer_collections
wmEventModifierFlag modifier
Definition WM_types.hh:774
struct ReportList * reports
struct PointerRNA * ptr
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
uint8_t flag
Definition wm_window.cc:145