Blender V4.5
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 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
246 ARegion *region = CTX_wm_region(C);
247 Main *bmain = CTX_data_main(C);
248 Scene *scene = CTX_data_scene(C);
249 ViewLayer *view_layer = CTX_data_view_layer(C);
250
252
253 if (RNA_boolean_get(op->ptr, "nested")) {
254 outliner_build_tree(bmain, scene, view_layer, space_outliner, region);
255
256 outliner_tree_traverse(space_outliner,
257 &space_outliner->tree,
258 0,
261 &data);
262
263 if (data.error) {
264 BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
265 return OPERATOR_CANCELLED;
266 }
267 }
268
269 if (data.collection == nullptr || !ID_IS_EDITABLE(data.collection) ||
270 ID_IS_OVERRIDE_LIBRARY(data.collection))
271 {
272 data.collection = scene->master_collection;
273 }
274
275 if (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) {
276 BKE_report(op->reports, RPT_ERROR, "Can't add a new collection to linked/override scene");
277 return OPERATOR_CANCELLED;
278 }
279
280 BKE_collection_add(bmain, data.collection, nullptr);
281
284
285 outliner_cleanup_tree(space_outliner);
287 return OPERATOR_FINISHED;
288}
289
291{
292 /* identifiers */
293 ot->name = "New Collection";
294 ot->idname = "OUTLINER_OT_collection_new";
295 ot->description = "Add a new collection inside selected collection";
296
297 /* API callbacks. */
298 ot->exec = collection_new_exec;
299 ot->poll = collection_new_poll;
300
301 /* flags */
303
304 /* properties */
306 ot->srna, "nested", true, "Nested", "Add as child of selected collection");
308}
309
311
312/* -------------------------------------------------------------------- */
315
321
322 /* Whether the processed operation should be allowed on liboverride collections, or not. */
324 /* Whether the processed operation should be allowed on hierarchy roots of liboverride
325 * collections, or not. */
327 /* When true, do not skip the hierarchy of children when a parent collection is selected. This is
328 * useful for deleting selected child collections, see: #126860. */
329 bool is_recursive = false;
330};
331
333{
334 CollectionEditData *data = static_cast<CollectionEditData *>(customdata);
336
337 if (!collection) {
339 }
340
341 if (collection->flag & COLLECTION_IS_MASTER) {
342 /* Skip - showing warning/error message might be misleading
343 * when deleting multiple collections, so just do nothing. */
344 return TRAVERSE_CONTINUE;
345 }
346
347 if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
349 if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) {
351 }
352 }
353 else {
354 if (!data->is_liboverride_allowed) {
356 }
357 }
358 }
359
360 /* Delete, duplicate and link don't edit children, those will come along
361 * with the parents. */
362 data->collections_to_edit.add(collection);
363 return data->is_recursive ? TRAVERSE_CONTINUE : TRAVERSE_SKIP_CHILDS;
364}
365
367 bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
368{
369 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
370
372 data.scene = scene;
373 data.space_outliner = space_outliner;
374 data.is_liboverride_allowed = false;
375 data.is_liboverride_hierarchy_root_allowed = do_hierarchy;
376 data.is_recursive = !do_hierarchy;
377
378 /* We first walk over and find the Collections we actually want to delete
379 * (ignoring duplicates). */
380 outliner_tree_traverse(space_outliner,
381 &space_outliner->tree,
382 0,
385 &data);
386
387 /* Effectively delete the collections. */
388 for (Collection *collection : data.collections_to_edit) {
389 /* Test in case collection got deleted as part of another one. */
390 if (BLI_findindex(&bmain->collections, collection) != -1) {
391 /* We cannot allow deleting collections that are indirectly linked,
392 * or that are used by (linked to...) other linked scene/collection. */
393 bool skip = false;
394 if (!ID_IS_EDITABLE(collection)) {
395 if (collection->id.tag & ID_TAG_INDIRECT) {
396 skip = true;
397 }
398 else {
399 LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
400 Collection *parent = cparent->collection;
401 if (!ID_IS_EDITABLE(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) {
402 skip = true;
403 break;
404 }
405 if (parent->flag & COLLECTION_IS_MASTER) {
407
408 ID *scene_owner = BKE_id_owner_get(&parent->id);
409 BLI_assert(scene_owner != nullptr);
410 BLI_assert(GS(scene_owner->name) == ID_SCE);
411 if (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
412 skip = true;
413 break;
414 }
415 }
416 }
417 }
418 }
419
420 if (!skip) {
421 BKE_collection_delete(bmain, collection, do_hierarchy);
422 }
423 else {
426 "Cannot delete collection '%s', it is either a linked one used by other "
427 "linked scenes/collections, or a library override one",
428 collection->id.name + 2);
429 }
430 }
431 }
432}
433
435{
436 Main *bmain = CTX_data_main(C);
437 Scene *scene = CTX_data_scene(C);
438 ViewLayer *view_layer = CTX_data_view_layer(C);
440 BKE_view_layer_synced_ensure(scene, view_layer);
441 const Base *basact_prev = BKE_view_layer_active_base_get(view_layer);
442
443 outliner_collection_delete(C, bmain, scene, op->reports, true);
444
447
449
450 BKE_view_layer_synced_ensure(scene, view_layer);
451 if (basact_prev != BKE_view_layer_active_base_get(view_layer)) {
452 WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
453 }
454
456
457 return OPERATOR_FINISHED;
458}
459
461{
462 /* identifiers */
463 ot->name = "Delete Hierarchy";
464 ot->idname = "OUTLINER_OT_collection_hierarchy_delete";
465 ot->description = "Delete selected collection hierarchies";
466
467 /* API callbacks. */
470
471 /* flags */
473}
474
476
477/* -------------------------------------------------------------------- */
480
485
487 void *customdata)
488{
490 TreeStoreElem *tselem = TREESTORE(te);
491
492 switch (tselem->type) {
494 data->layer_collection = static_cast<LayerCollection *>(te->directdata);
495 return TRAVERSE_BREAK;
496 case TSE_R_LAYER:
499 return TRAVERSE_CONTINUE;
500 default:
502 }
503}
504
506{
507 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
508
510
511 outliner_tree_traverse(space_outliner,
512 &space_outliner->tree,
513 0,
516 &data);
517 return data.layer_collection;
518}
519
521{
522 Scene *scene = CTX_data_scene(C);
523 ViewLayer *view_layer = CTX_data_view_layer(C);
524 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
525 bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
526
527 IDsSelectedData selected_collections{};
528 outliner_tree_traverse(space_outliner,
529 &space_outliner->tree,
530 0,
533 &selected_collections);
534
535 if (selected_collections.selected_array.first == nullptr) {
536 return OPERATOR_CANCELLED;
537 }
538
539 LISTBASE_FOREACH (LinkData *, link, &selected_collections.selected_array) {
540 TreeElement *te = static_cast<TreeElement *>(link->data);
542 LayerCollection *layer_collection = static_cast<LayerCollection *>(te->directdata);
543 BKE_layer_collection_objects_select(scene, view_layer, layer_collection, deselect);
544 }
545 }
546
547 BLI_freelistN(&selected_collections.selected_array);
551
552 return OPERATOR_FINISHED;
553}
554
556{
557 /* identifiers */
558 ot->name = "Select Objects";
559 ot->idname = "OUTLINER_OT_collection_objects_select";
560 ot->description = "Select objects in collection";
561
562 /* API callbacks. */
565
566 /* flags */
568}
569
571{
572 /* identifiers */
573 ot->name = "Deselect Objects";
574 ot->idname = "OUTLINER_OT_collection_objects_deselect";
575 ot->description = "Deselect objects in collection";
576
577 /* API callbacks. */
580
581 /* flags */
583}
584
586
587/* -------------------------------------------------------------------- */
590
594
596 void *customdata)
597{
598 CollectionDuplicateData *data = static_cast<CollectionDuplicateData *>(customdata);
599 TreeStoreElem *tselem = TREESTORE(te);
600
601 switch (tselem->type) {
603 data->te = te;
604 return TRAVERSE_BREAK;
605 case TSE_R_LAYER:
608 default:
609 return TRAVERSE_CONTINUE;
610 }
611}
612
614{
615 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
616
618
619 outliner_tree_traverse(space_outliner,
620 &space_outliner->tree,
621 0,
624 &data);
625 return data.te;
626}
627
629{
630 Main *bmain = CTX_data_main(C);
631 const bool linked = strstr(op->idname, "linked") != nullptr;
632 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
633
634 IDsSelectedData selected_collections{};
635 outliner_tree_traverse(space_outliner,
636 &space_outliner->tree,
637 0,
640 &selected_collections);
641
642 /* Can happen when calling from a key binding. */
643 if (BLI_listbase_is_empty(&selected_collections.selected_array)) {
644 BKE_report(op->reports, RPT_ERROR, "No active collection");
645 return OPERATOR_CANCELLED;
646 }
647
648 int failed_count = 0;
649 LISTBASE_FOREACH (LinkData *, link, &selected_collections.selected_array) {
650 TreeElement *te = static_cast<TreeElement *>(link->data);
653 nullptr;
654 if (!parent) {
655 failed_count += 1;
656 continue;
657 }
658 CollectionChild *child = BKE_collection_child_find(parent, collection);
659
660 /* We are allowed to duplicated linked collections (they will become local IDs then),
661 * but we should not allow its parent to be a linked ID, ever.
662 * This can happen when a whole scene is linked e.g. */
663 if (parent != nullptr && (!ID_IS_EDITABLE(parent) || ID_IS_OVERRIDE_LIBRARY(parent))) {
664 Scene *scene = CTX_data_scene(C);
665 parent = (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) ?
666 nullptr :
667 scene->master_collection;
668 }
669 else if (parent != nullptr && (parent->flag & COLLECTION_IS_MASTER) != 0) {
671
672 Scene *scene_owner = reinterpret_cast<Scene *>(BKE_id_owner_get(&parent->id));
673 BLI_assert(scene_owner != nullptr);
674 BLI_assert(GS(scene_owner->id.name) == ID_SCE);
675
676 if (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
677 scene_owner = CTX_data_scene(C);
678 parent = (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) ?
679 nullptr :
680 scene_owner->master_collection;
681 }
682 }
683
684 const eDupli_ID_Flags dupli_flags = (eDupli_ID_Flags)(USER_DUP_OBJECT |
685 (linked ? 0 : U.dupflag));
687 bmain, parent, child, collection, dupli_flags, LIB_ID_DUPLICATE_IS_ROOT_ID);
688 }
689
690 if (failed_count != 0) {
693 "Unable to duplicate %d of the selected collections. "
694 "Could not find a valid parent collection for the new duplicate, "
695 "they won't be linked to any view layer",
696 failed_count);
697 }
698
699 BLI_freelistN(&selected_collections.selected_array);
703
704 return OPERATOR_FINISHED;
705}
706
708{
709 /* identifiers */
710 ot->name = "Duplicate Linked Collection";
711 ot->idname = "OUTLINER_OT_collection_duplicate_linked";
712 ot->description =
713 "Recursively duplicate the collection, all its children and objects, with linked object "
714 "data";
715
716 /* API callbacks. */
719
720 /* flags */
722}
723
725{
726 /* identifiers */
727 ot->name = "Duplicate Collection";
728 ot->idname = "OUTLINER_OT_collection_duplicate";
729 ot->description =
730 "Recursively duplicate the collection, all its children, objects and object data";
731
732 /* API callbacks. */
735
736 /* flags */
738}
739
741
742/* -------------------------------------------------------------------- */
745
747{
748 Main *bmain = CTX_data_main(C);
749 Scene *scene = CTX_data_scene(C);
750 Collection *active_collection = CTX_data_layer_collection(C)->collection;
751 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
752
754 data.scene = scene;
755 data.space_outliner = space_outliner;
756 data.is_liboverride_allowed = false; /* No linking of non-root collections. */
757 data.is_liboverride_hierarchy_root_allowed = true;
758
759 if ((!ID_IS_EDITABLE(active_collection) || ID_IS_OVERRIDE_LIBRARY(active_collection)) ||
760 ((active_collection->flag & COLLECTION_IS_MASTER) &&
761 (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene))))
762 {
764 op->reports, RPT_ERROR, "Cannot add a collection to a linked/override collection/scene");
765 return OPERATOR_CANCELLED;
766 }
767
768 /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */
769 outliner_tree_traverse(space_outliner,
770 &space_outliner->tree,
771 0,
774 &data);
775
776 /* Effectively link the collections. */
777 for (Collection *collection : data.collections_to_edit) {
778 BKE_collection_child_add(bmain, active_collection, collection);
779 id_fake_user_clear(&collection->id);
780 }
781
782 DEG_id_tag_update(&active_collection->id, ID_RECALC_SYNC_TO_EVAL);
784
786
787 return OPERATOR_FINISHED;
788}
789
791{
792 /* identifiers */
793 ot->name = "Link Collection";
794 ot->idname = "OUTLINER_OT_collection_link";
795 ot->description = "Link selected collections to active scene";
796
797 /* API callbacks. */
798 ot->exec = collection_link_exec;
800
801 /* flags */
803}
804
806
807/* -------------------------------------------------------------------- */
810
812{
813 Main *bmain = CTX_data_main(C);
814 Scene *scene = CTX_data_scene(C);
815 ViewLayer *view_layer = CTX_data_view_layer(C);
816 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
818 data.scene = scene;
819 data.space_outliner = space_outliner;
820 data.is_liboverride_allowed = true;
821 data.is_liboverride_hierarchy_root_allowed = true;
822
823 /* We first walk over and find the Collections we actually want to instance
824 * (ignoring duplicates). */
825 outliner_tree_traverse(space_outliner,
826 &space_outliner->tree,
827 0,
830 &data);
831
832 /* Find an active collection to add to, that doesn't give dependency cycles. */
833 LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
834
835 for (Collection *collection : data.collections_to_edit) {
836 while (BKE_collection_cycle_find(active_lc->collection, collection)) {
837 active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
838 }
839 }
840
841 /* Effectively instance the collections. */
842 for (Collection *collection : data.collections_to_edit) {
844 C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, nullptr, false, 0);
845 ob->instance_collection = collection;
847 id_us_plus(&collection->id);
848 }
849
851
853
854 return OPERATOR_FINISHED;
855}
856
858{
859 /* identifiers */
860 ot->name = "Instance Collection";
861 ot->idname = "OUTLINER_OT_collection_instance";
862 ot->description = "Instance selected collections to active scene";
863
864 /* API callbacks. */
867
868 /* flags */
870}
871
873
874/* -------------------------------------------------------------------- */
877
879{
880 CollectionEditData *data = static_cast<CollectionEditData *>(customdata);
881 TreeStoreElem *tselem = TREESTORE(te);
882
883 if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
884 return TRAVERSE_CONTINUE;
885 }
886
887 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
888
890 /* skip - showing warning/error message might be misleading
891 * when deleting multiple collections, so just do nothing */
892 }
893 else {
894 /* Delete, duplicate and link don't edit children, those will come along
895 * with the parents. */
896 data->layer_collections_to_edit.add(lc);
897 }
898
899 return TRAVERSE_CONTINUE;
900}
901
903{
904 /* Poll function so the right click menu show current state of selected collections. */
905 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
906 if (!(space_outliner && space_outliner->outlinevis == SO_VIEW_LAYER)) {
907 return false;
908 }
909
910 Scene *scene = CTX_data_scene(C);
912 data.scene = scene;
913 data.space_outliner = space_outliner;
914 data.is_liboverride_allowed = true;
915 data.is_liboverride_hierarchy_root_allowed = true;
916 bool result = false;
917
918 outliner_tree_traverse(space_outliner,
919 &space_outliner->tree,
920 0,
923 &data);
924
925 for (LayerCollection *lc : data.layer_collections_to_edit) {
926 if (clear && (lc->flag & flag)) {
927 result = true;
928 }
929 else if (!clear && !(lc->flag & flag)) {
930 result = true;
931 }
932 }
933
934 return result;
935}
936
941
946
951
956
961
966
968{
969 Main *bmain = CTX_data_main(C);
970 Scene *scene = CTX_data_scene(C);
971 ViewLayer *view_layer = CTX_data_view_layer(C);
972 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
974 data.scene = scene;
975 data.space_outliner = space_outliner;
976 data.is_liboverride_allowed = true;
977 data.is_liboverride_hierarchy_root_allowed = true;
978 bool clear = strstr(op->idname, "clear") != nullptr;
979 int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
980 strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
982
983 outliner_tree_traverse(space_outliner,
984 &space_outliner->tree,
985 0,
988 &data);
989
990 for (LayerCollection *lc : data.layer_collections_to_edit) {
992 }
993
996
998
999 return OPERATOR_FINISHED;
1000}
1001
1003{
1004 /* identifiers */
1005 ot->name = "Disable from View Layer";
1006 ot->idname = "OUTLINER_OT_collection_exclude_set";
1007 ot->description = "Exclude collection from the active view layer";
1008
1009 /* API callbacks. */
1012
1013 /* flags */
1014 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1015}
1016
1018{
1019 /* identifiers */
1020 ot->name = "Enable in View Layer";
1021 ot->idname = "OUTLINER_OT_collection_exclude_clear";
1022 ot->description = "Include collection in the active view layer";
1023
1024 /* API callbacks. */
1027
1028 /* flags */
1029 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1030}
1031
1033{
1034 /* identifiers */
1035 ot->name = "Set Holdout";
1036 ot->idname = "OUTLINER_OT_collection_holdout_set";
1037 ot->description = "Mask collection in the active view layer";
1038
1039 /* API callbacks. */
1042
1043 /* flags */
1044 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1045}
1046
1048{
1049 /* identifiers */
1050 ot->name = "Clear Holdout";
1051 ot->idname = "OUTLINER_OT_collection_holdout_clear";
1052 ot->description = "Clear masking of collection in the active view layer";
1053
1054 /* API callbacks. */
1057
1058 /* flags */
1059 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1060}
1061
1063{
1064 /* identifiers */
1065 ot->name = "Set Indirect Only";
1066 ot->idname = "OUTLINER_OT_collection_indirect_only_set";
1067 ot->description =
1068 "Set collection to only contribute indirectly (through shadows and reflections) in the view "
1069 "layer";
1070
1071 /* API callbacks. */
1074
1075 /* flags */
1076 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1077}
1078
1080{
1081 /* identifiers */
1082 ot->name = "Clear Indirect Only";
1083 ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
1084 ot->description = "Clear collection contributing only indirectly in the view layer";
1085
1086 /* API callbacks. */
1089
1090 /* flags */
1091 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1092}
1093
1095
1096/* -------------------------------------------------------------------- */
1099
1101{
1102 Scene *scene = CTX_data_scene(C);
1103 ViewLayer *view_layer = CTX_data_view_layer(C);
1104 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1105 const bool extend = RNA_boolean_get(op->ptr, "extend");
1107 data.scene = scene;
1108 data.space_outliner = space_outliner;
1109 data.is_liboverride_allowed = true;
1110 data.is_liboverride_hierarchy_root_allowed = true;
1111 outliner_tree_traverse(space_outliner,
1112 &space_outliner->tree,
1113 0,
1116 &data);
1117
1118 for (LayerCollection *layer_collection : data.layer_collections_to_edit) {
1119 if (extend) {
1120 BKE_layer_collection_isolate_global(scene, view_layer, layer_collection, true);
1121 }
1122 else {
1123 PropertyRNA *prop = RNA_struct_type_find_property(&RNA_LayerCollection, "hide_viewport");
1125 &scene->id, &RNA_LayerCollection, layer_collection);
1126
1127 /* We need to flip the value because the isolate flag routine was designed to work from the
1128 * outliner as a callback. That means the collection visibility was set before the callback
1129 * was called. */
1130 const bool value = !RNA_property_boolean_get(&ptr, prop);
1132 scene, view_layer, layer_collection, nullptr, prop, "hide_viewport", value);
1133 break;
1134 }
1135 }
1136
1139
1141 return OPERATOR_FINISHED;
1142}
1143
1145 wmOperator *op,
1146 const wmEvent *event)
1147{
1148 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
1149 if (!RNA_property_is_set(op->ptr, prop) && (event->modifier & KM_SHIFT)) {
1150 RNA_property_boolean_set(op->ptr, prop, true);
1151 }
1152 return collection_isolate_exec(C, op);
1153}
1154
1156{
1157 /* identifiers */
1158 ot->name = "Isolate Collection";
1159 ot->idname = "OUTLINER_OT_collection_isolate";
1160 ot->description = "Hide all but this collection and its parents";
1161
1162 /* API callbacks. */
1164 ot->invoke = collection_isolate_invoke;
1166
1167 /* flags */
1168 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1169
1170 /* properties */
1172 ot->srna, "extend", false, "Extend", "Extend current visible collections");
1174}
1175
1180
1185
1187{
1189 return false;
1190 }
1191 return outliner_active_layer_collection(C) != nullptr;
1192}
1193
1195{
1196 Scene *scene = CTX_data_scene(C);
1197 ViewLayer *view_layer = CTX_data_view_layer(C);
1198 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1199 const bool is_inside = strstr(op->idname, "inside") != nullptr;
1200 const bool show = strstr(op->idname, "show") != nullptr;
1202 data.scene = scene;
1203 data.space_outliner = space_outliner;
1204 data.is_liboverride_allowed = true;
1205 data.is_liboverride_hierarchy_root_allowed = true;
1206
1207 outliner_tree_traverse(space_outliner,
1208 &space_outliner->tree,
1209 0,
1212 &data);
1213
1214 for (LayerCollection *layer_collection : data.layer_collections_to_edit) {
1215 BKE_layer_collection_set_visible(scene, view_layer, layer_collection, show, is_inside);
1216 }
1217
1220
1222 return OPERATOR_FINISHED;
1223}
1224
1226{
1227 /* identifiers */
1228 ot->name = "Show Collection";
1229 ot->idname = "OUTLINER_OT_collection_show";
1230 ot->description = "Show the collection in this view layer";
1231
1232 /* API callbacks. */
1234 ot->poll = collection_show_poll;
1235
1236 /* flags */
1237 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1238}
1239
1241{
1242 /* identifiers */
1243 ot->name = "Hide Collection";
1244 ot->idname = "OUTLINER_OT_collection_hide";
1245 ot->description = "Hide the collection in this view layer";
1246
1247 /* API callbacks. */
1249 ot->poll = collection_hide_poll;
1250
1251 /* flags */
1252 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1253}
1254
1256{
1257 /* identifiers */
1258 ot->name = "Show Inside Collection";
1259 ot->idname = "OUTLINER_OT_collection_show_inside";
1260 ot->description = "Show all the objects and collections inside the collection";
1261
1262 /* API callbacks. */
1264 ot->poll = collection_inside_poll;
1265
1266 /* flags */
1267 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1268}
1269
1271{
1272 /* identifiers */
1273 ot->name = "Hide Inside Collection";
1274 ot->idname = "OUTLINER_OT_collection_hide_inside";
1275 ot->description = "Hide all the objects and collections inside the collection";
1276
1277 /* API callbacks. */
1279 ot->poll = collection_inside_poll;
1280
1281 /* flags */
1282 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1283}
1284
1286
1287/* -------------------------------------------------------------------- */
1290
1291static bool collection_flag_poll(bContext *C, bool clear, int flag)
1292{
1294 return false;
1295 }
1296
1298 if (te == nullptr) {
1299 return false;
1300 }
1301
1303 if (collection == nullptr) {
1304 return false;
1305 }
1306
1307 if (clear && (collection->flag & flag)) {
1308 return true;
1309 }
1310 if (!clear && !(collection->flag & flag)) {
1311 return true;
1312 }
1313
1314 return false;
1315}
1316
1321
1326
1331
1336
1338{
1339 Main *bmain = CTX_data_main(C);
1340 Scene *scene = CTX_data_scene(C);
1341 ViewLayer *view_layer = CTX_data_view_layer(C);
1342 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1343 const bool is_render = strstr(op->idname, "render");
1344 const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
1347 data.scene = scene;
1348 data.space_outliner = space_outliner;
1349 data.is_liboverride_allowed = true;
1350 data.is_liboverride_hierarchy_root_allowed = true;
1351 const bool has_layer_collection = space_outliner->outlinevis == SO_VIEW_LAYER;
1352
1353 if (has_layer_collection) {
1354 outliner_tree_traverse(space_outliner,
1355 &space_outliner->tree,
1356 0,
1359 &data);
1360 for (LayerCollection *layer_collection : data.layer_collections_to_edit) {
1361 Collection *collection = layer_collection->collection;
1362 if (!BKE_id_is_editable(bmain, &collection->id)) {
1363 continue;
1364 }
1365 if (clear) {
1366 collection->flag &= ~flag;
1367 }
1368 else {
1369 collection->flag |= flag;
1370 }
1371
1372 /* Make sure (at least for this view layer) the collection is visible. */
1373 if (clear && !is_render) {
1374 layer_collection->flag &= ~LAYER_COLLECTION_HIDE;
1375 }
1376 }
1377 }
1378 else {
1379 outliner_tree_traverse(space_outliner,
1380 &space_outliner->tree,
1381 0,
1384 &data);
1385 for (Collection *collection : data.collections_to_edit) {
1386 if (!BKE_id_is_editable(bmain, &collection->id)) {
1387 continue;
1388 }
1389
1390 if (clear) {
1391 collection->flag &= ~flag;
1392 }
1393 else {
1394 collection->flag |= flag;
1395 }
1396 }
1397 }
1398
1401
1402 if (!is_render) {
1404 }
1405
1407 return OPERATOR_FINISHED;
1408}
1409
1411{
1412 /* identifiers */
1413 ot->name = "Enable Collection";
1414 ot->idname = "OUTLINER_OT_collection_enable";
1415 ot->description = "Enable viewport display in the view layers";
1416
1417 /* API callbacks. */
1418 ot->exec = collection_flag_exec;
1419 ot->poll = collection_enable_poll;
1420
1421 /* flags */
1422 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1423}
1424
1426{
1427 /* identifiers */
1428 ot->name = "Disable Collection";
1429 ot->idname = "OUTLINER_OT_collection_disable";
1430 ot->description = "Disable viewport display in the view layers";
1431
1432 /* API callbacks. */
1433 ot->exec = collection_flag_exec;
1435
1436 /* flags */
1437 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1438}
1439
1441{
1442 /* identifiers */
1443 ot->name = "Enable Collection in Render";
1444 ot->idname = "OUTLINER_OT_collection_enable_render";
1445 ot->description = "Render the collection";
1446
1447 /* API callbacks. */
1448 ot->exec = collection_flag_exec;
1450
1451 /* flags */
1452 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1453}
1454
1456{
1457 /* identifiers */
1458 ot->name = "Disable Collection in Render";
1459 ot->idname = "OUTLINER_OT_collection_disable_render";
1460 ot->description = "Do not render this collection";
1461
1462 /* API callbacks. */
1463 ot->exec = collection_flag_exec;
1465
1466 /* flags */
1467 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1468}
1469
1477
1479
1480/* -------------------------------------------------------------------- */
1483
1485{
1486 OutlinerHideEditData *data = static_cast<OutlinerHideEditData *>(customdata);
1487 TreeStoreElem *tselem = TREESTORE(te);
1488
1489 if (tselem == nullptr) {
1490 return TRAVERSE_CONTINUE;
1491 }
1492
1493 if (tselem->type == TSE_LAYER_COLLECTION) {
1494 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
1495
1497 /* Skip - showing warning/error message might be misleading
1498 * when deleting multiple collections, so just do nothing. */
1499 }
1500 else {
1501 /* Delete, duplicate and link don't edit children,
1502 * those will come along with the parents. */
1503 data->collections_to_edit.add(lc);
1504 }
1505 }
1506 else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1507 Object *ob = (Object *)tselem->id;
1508 BKE_view_layer_synced_ensure(data->scene, data->view_layer);
1509 Base *base = BKE_view_layer_base_find(data->view_layer, ob);
1510 data->bases_to_edit.add(base);
1511 }
1512
1513 return TRAVERSE_CONTINUE;
1514}
1515
1517{
1518 Scene *scene = CTX_data_scene(C);
1519 ViewLayer *view_layer = CTX_data_view_layer(C);
1520 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1522 data.scene = scene;
1523 data.view_layer = view_layer;
1524 data.space_outliner = space_outliner;
1525
1526 outliner_tree_traverse(space_outliner,
1527 &space_outliner->tree,
1528 0,
1531 &data);
1532
1533 for (LayerCollection *layer_collection : data.collections_to_edit) {
1534 BKE_layer_collection_set_visible(scene, view_layer, layer_collection, false, false);
1535 }
1536
1537 for (Base *base : data.bases_to_edit) {
1538 base->flag |= BASE_HIDDEN;
1539 }
1540
1543
1545 return OPERATOR_FINISHED;
1546}
1547
1549{
1550 /* identifiers */
1551 ot->name = "Hide";
1552 ot->idname = "OUTLINER_OT_hide";
1553 ot->description = "Hide selected objects and collections";
1554
1555 /* API callbacks. */
1556 ot->exec = outliner_hide_exec;
1558
1559 /* flags */
1560 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1561}
1562
1564{
1565 Scene *scene = CTX_data_scene(C);
1566 ViewLayer *view_layer = CTX_data_view_layer(C);
1567
1568 /* Unhide all the collections. */
1569 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1570 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1572 }
1573
1574 /* Unhide all objects. */
1575 BKE_view_layer_synced_ensure(scene, view_layer);
1577 base->flag &= ~BASE_HIDDEN;
1578 }
1579
1582
1584 return OPERATOR_FINISHED;
1585}
1586
1588{
1589 /* identifiers */
1590 ot->name = "Unhide All";
1591 ot->idname = "OUTLINER_OT_unhide_all";
1592 ot->description = "Unhide all objects and collections";
1593
1594 /* API callbacks. */
1597
1598 /* flags */
1599 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1600}
1601
1603
1604/* -------------------------------------------------------------------- */
1607
1609{
1610 Scene *scene = CTX_data_scene(C);
1611 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1612 const short color_tag = RNA_enum_get(op->ptr, "color");
1613
1614 IDsSelectedData selected{};
1615
1616 outliner_tree_traverse(space_outliner,
1617 &space_outliner->tree,
1618 0,
1621 &selected);
1622
1623 LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
1624 TreeElement *te_selected = (TreeElement *)link->data;
1625
1626 Collection *collection = outliner_collection_from_tree_element(te_selected);
1627 if (collection == scene->master_collection) {
1628 continue;
1629 }
1630 if (!BKE_id_is_editable(CTX_data_main(C), &collection->id)) {
1631 BKE_report(op->reports, RPT_WARNING, "Can't add a color tag to a linked collection");
1632 continue;
1633 }
1634
1635 collection->color_tag = color_tag;
1636 };
1637
1638 BLI_freelistN(&selected.selected_array);
1639
1641
1642 return OPERATOR_FINISHED;
1643}
1644
1646{
1647 /* identifiers */
1648 ot->name = "Set Color Tag";
1649 ot->idname = "OUTLINER_OT_collection_color_tag_set";
1650 ot->description = "Set a color tag for the selected collections";
1651
1652 /* API callbacks. */
1655
1656 /* flags */
1657 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1658
1660 ot->srna, "color", rna_enum_collection_color_items, COLLECTION_COLOR_NONE, "Color Tag", "");
1661}
1662
1664
1665} // 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)
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:2503
void id_us_plus(ID *id)
Definition lib_id.cc:353
ID * BKE_id_owner_get(ID *id, const bool debug_relationship_assert=true)
Definition lib_id.cc:2491
void id_fake_user_clear(ID *id)
Definition lib_id.cc:399
@ LIB_ID_DUPLICATE_IS_ROOT_ID
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
#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_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:687
@ ID_RECALC_SELECT
Definition DNA_ID.h:1009
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1012
@ ID_TAG_INDIRECT
Definition DNA_ID.h:756
@ 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
@ BASE_HIDDEN
@ LAYER_COLLECTION_HIDE
@ LAYER_COLLECTION_EXCLUDE
@ LAYER_COLLECTION_INDIRECT_ONLY
@ LAYER_COLLECTION_HOLDOUT
Object is a sort of wrapper for general info.
@ OB_DUPLICOLLECTION
@ OB_EMPTY
@ TSE_SELECTED
@ TSE_VIEW_COLLECTION_BASE
@ TSE_SCENE_COLLECTION_BASE
@ TSE_LAYER_COLLECTION
@ TSE_SOME_ID
@ TSE_R_LAYER
@ 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:330
#define C
Definition RandGen.cpp:29
@ KM_SHIFT
Definition WM_types.hh:275
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define ND_OB_SELECT
Definition WM_types.hh:439
#define NC_SCENE
Definition WM_types.hh:375
#define ND_LAYER_CONTENT
Definition WM_types.hh:450
ReportList * reports
Definition WM_types.hh:1025
#define ND_LAYER
Definition WM_types.hh:447
#define U
BMesh const char void * data
static bool is_inside(int x, int y, int cols, int rows)
Definition filesel.cc:772
#define active
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(_id)
#define GS(a)
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)
void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOutliner *space_outliner, ARegion *region)
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)
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
Collection_Runtime runtime
Definition DNA_ID.h:404
int tag
Definition DNA_ID.h:424
short flag
Definition DNA_ID.h:420
char name[66]
Definition DNA_ID.h:415
ListBase layer_collections
struct Collection * collection
void * first
ListBase collections
Definition BKE_main.hh:267
short transflag
struct Collection * instance_collection
struct Collection * master_collection
View3DCursor cursor
ListBase layer_collections
wmEventModifierFlag modifier
Definition WM_types.hh:771
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:4226
wmOperatorType * ot
Definition wm_files.cc:4225
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
uint8_t flag
Definition wm_window.cc:139