Blender V4.3
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
9#include <cstring>
10
11#include "BLI_listbase.h"
12#include "BLI_utildefines.h"
13
14#include "DNA_ID.h"
16#include "DNA_object_types.h"
17
18#include "BKE_collection.hh"
19#include "BKE_context.hh"
20#include "BKE_layer.hh"
21#include "BKE_lib_id.hh"
22#include "BKE_main.hh"
23#include "BKE_report.hh"
24
25#include "DEG_depsgraph.hh"
27
28#include "ED_object.hh"
29#include "ED_outliner.hh"
30#include "ED_screen.hh"
31
32#include "WM_api.hh"
33#include "WM_message.hh"
34#include "WM_types.hh"
35
36#include "RNA_access.hh"
37#include "RNA_define.hh"
38#include "RNA_enum_types.hh"
39
40#include "outliner_intern.hh" /* own include */
41
43
44/* -------------------------------------------------------------------- */
49{
50 TreeStoreElem *tselem = TREESTORE(te);
51
52 if (!tselem) {
53 return false;
54 }
55
56 if (ELEM(
58 {
59 return true;
60 }
61 if ((tselem->type == TSE_SOME_ID) && te->idcode == ID_GR) {
62 return true;
63 }
64
65 return false;
66}
67
69{
70 TreeStoreElem *tselem = TREESTORE(te);
71
72 if (!tselem) {
73 return nullptr;
74 }
75
76 if (tselem->type == TSE_LAYER_COLLECTION) {
77 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
78 return lc->collection;
79 }
81 Scene *scene = (Scene *)tselem->id;
82 return scene->master_collection;
83 }
84 if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_GR)) {
85 return (Collection *)tselem->id;
86 }
87
88 return nullptr;
89}
90
92{
93 IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata);
94 TreeStoreElem *tselem = TREESTORE(te);
95
97 BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
98 return TRAVERSE_CONTINUE;
99 }
100
101 if ((tselem->type != TSE_SOME_ID) || (tselem->id && GS(tselem->id->name) != ID_GR)) {
103 }
104
105 return TRAVERSE_CONTINUE;
106}
107
109{
110 IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata);
111 TreeStoreElem *tselem = TREESTORE(te);
112
114 return TRAVERSE_CONTINUE;
115 }
116
117 if ((tselem->type != TSE_SOME_ID) || (tselem->id == nullptr) || (GS(tselem->id->name) != ID_OB))
118 {
120 }
121
122 BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
123
124 return TRAVERSE_CONTINUE;
125}
126
127} // namespace blender::ed::outliner
128
130{
131 using namespace blender::ed::outliner;
132
133 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
134 IDsSelectedData data = {{nullptr}};
135 outliner_tree_traverse(space_outliner,
136 &space_outliner->tree,
137 0,
139 outliner_collect_selected_objects,
140 &data);
141 LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
142 TreeElement *ten_selected = (TreeElement *)link->data;
143 Object *ob = (Object *)TREESTORE(ten_selected)->id;
144 BLI_addtail(objects, BLI_genericNodeN(ob));
145 }
146 BLI_freelistN(&data.selected_array);
147}
148
149namespace blender::ed::outliner {
150
153/* -------------------------------------------------------------------- */
157} // namespace blender::ed::outliner
158
160{
161 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
162 return (space_outliner != nullptr) &&
164}
165
166namespace blender::ed::outliner {
167
169{
170 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
171 return (space_outliner != nullptr) && (space_outliner->outlinevis == SO_VIEW_LAYER);
172}
173
175{
177 return false;
178 }
179 Scene *scene = CTX_data_scene(C);
180 if (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) {
181 return false;
182 }
183 return true;
184}
185
187{
189 return false;
190 }
192 return false;
193 }
194 return true;
195}
196
199/* -------------------------------------------------------------------- */
207
209{
210 CollectionNewData *data = static_cast<CollectionNewData *>(customdata);
212
213 if (!collection) {
215 }
216
217 if (data->collection != nullptr) {
218 data->error = true;
219 return TRAVERSE_BREAK;
220 }
221
222 data->collection = collection;
223 return TRAVERSE_CONTINUE;
224}
225
227{
228 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
229 ARegion *region = CTX_wm_region(C);
230 Main *bmain = CTX_data_main(C);
231 Scene *scene = CTX_data_scene(C);
232 ViewLayer *view_layer = CTX_data_view_layer(C);
233
234 CollectionNewData data{};
235
236 if (RNA_boolean_get(op->ptr, "nested")) {
237 outliner_build_tree(bmain, scene, view_layer, space_outliner, region);
238
239 outliner_tree_traverse(space_outliner,
240 &space_outliner->tree,
241 0,
244 &data);
245
246 if (data.error) {
247 BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
248 return OPERATOR_CANCELLED;
249 }
250 }
251
252 if (data.collection == nullptr || !ID_IS_EDITABLE(data.collection) ||
253 ID_IS_OVERRIDE_LIBRARY(data.collection))
254 {
255 data.collection = scene->master_collection;
256 }
257
258 if (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) {
259 BKE_report(op->reports, RPT_ERROR, "Can't add a new collection to linked/override scene");
260 return OPERATOR_CANCELLED;
261 }
262
263 BKE_collection_add(bmain, data.collection, nullptr);
264
265 DEG_id_tag_update(&data.collection->id, ID_RECALC_SYNC_TO_EVAL);
267
268 outliner_cleanup_tree(space_outliner);
270 return OPERATOR_FINISHED;
271}
272
274{
275 /* identifiers */
276 ot->name = "New Collection";
277 ot->idname = "OUTLINER_OT_collection_new";
278 ot->description = "Add a new collection inside selected collection";
279
280 /* api callbacks */
283
284 /* flags */
286
287 /* properties */
289 ot->srna, "nested", true, "Nested", "Add as child of selected collection");
291}
292
295/* -------------------------------------------------------------------- */
303
304 /* Whether the processed operation should be allowed on liboverride collections, or not. */
306 /* Whether the processed operation should be allowed on hierarchy roots of liboverride
307 * collections, or not. */
309 /* When true, do not skip the hierarchy of children when a parent collection is selected. This is
310 * useful for deleting selected child collections, see: #126860. */
311 bool is_recursive = false;
312};
313
315{
316 CollectionEditData *data = static_cast<CollectionEditData *>(customdata);
318
319 if (!collection) {
321 }
322
323 if (collection->flag & COLLECTION_IS_MASTER) {
324 /* Skip - showing warning/error message might be misleading
325 * when deleting multiple collections, so just do nothing. */
326 return TRAVERSE_CONTINUE;
327 }
328
329 if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
331 if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) {
333 }
334 }
335 else {
336 if (!data->is_liboverride_allowed) {
338 }
339 }
340 }
341
342 /* Delete, duplicate and link don't edit children, those will come along
343 * with the parents. */
344 BLI_gset_add(data->collections_to_edit, collection);
345 return data->is_recursive ? TRAVERSE_CONTINUE : TRAVERSE_SKIP_CHILDS;
346}
347
349 bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
350{
351 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
352
353 CollectionEditData data{};
354 data.scene = scene;
355 data.space_outliner = space_outliner;
356 data.is_liboverride_allowed = false;
357 data.is_liboverride_hierarchy_root_allowed = do_hierarchy;
358 data.is_recursive = !do_hierarchy;
359
360 data.collections_to_edit = BLI_gset_ptr_new(__func__);
361
362 /* We first walk over and find the Collections we actually want to delete
363 * (ignoring duplicates). */
364 outliner_tree_traverse(space_outliner,
365 &space_outliner->tree,
366 0,
369 &data);
370
371 /* Effectively delete the collections. */
372 GSetIterator collections_to_edit_iter;
373 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
374 Collection *collection = static_cast<Collection *>(
375 BLI_gsetIterator_getKey(&collections_to_edit_iter));
376
377 /* Test in case collection got deleted as part of another one. */
378 if (BLI_findindex(&bmain->collections, collection) != -1) {
379 /* We cannot allow deleting collections that are indirectly linked,
380 * or that are used by (linked to...) other linked scene/collection. */
381 bool skip = false;
382 if (!ID_IS_EDITABLE(collection)) {
383 if (collection->id.tag & ID_TAG_INDIRECT) {
384 skip = true;
385 }
386 else {
387 LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
388 Collection *parent = cparent->collection;
389 if (!ID_IS_EDITABLE(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) {
390 skip = true;
391 break;
392 }
393 if (parent->flag & COLLECTION_IS_MASTER) {
395
396 ID *scene_owner = BKE_id_owner_get(&parent->id);
397 BLI_assert(scene_owner != nullptr);
398 BLI_assert(GS(scene_owner->name) == ID_SCE);
399 if (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
400 skip = true;
401 break;
402 }
403 }
404 }
405 }
406 }
407
408 if (!skip) {
409 BKE_collection_delete(bmain, collection, do_hierarchy);
410 }
411 else {
412 BKE_reportf(reports,
414 "Cannot delete collection '%s', it is either a linked one used by other "
415 "linked scenes/collections, or a library override one",
416 collection->id.name + 2);
417 }
418 }
419 }
420
421 BLI_gset_free(data.collections_to_edit, nullptr);
422}
423
425{
426 Main *bmain = CTX_data_main(C);
427 Scene *scene = CTX_data_scene(C);
428 ViewLayer *view_layer = CTX_data_view_layer(C);
429 wmMsgBus *mbus = CTX_wm_message_bus(C);
430 BKE_view_layer_synced_ensure(scene, view_layer);
431 const Base *basact_prev = BKE_view_layer_active_base_get(view_layer);
432
433 outliner_collection_delete(C, bmain, scene, op->reports, true);
434
437
439
440 BKE_view_layer_synced_ensure(scene, view_layer);
441 if (basact_prev != BKE_view_layer_active_base_get(view_layer)) {
442 WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
443 }
444
446
447 return OPERATOR_FINISHED;
448}
449
451{
452 /* identifiers */
453 ot->name = "Delete Hierarchy";
454 ot->idname = "OUTLINER_OT_collection_hierarchy_delete";
455 ot->description = "Delete selected collection hierarchies";
456
457 /* api callbacks */
460
461 /* flags */
463}
464
467/* -------------------------------------------------------------------- */
475
477 void *customdata)
478{
479 CollectionObjectsSelectData *data = static_cast<CollectionObjectsSelectData *>(customdata);
480 TreeStoreElem *tselem = TREESTORE(te);
481
482 switch (tselem->type) {
484 data->layer_collection = static_cast<LayerCollection *>(te->directdata);
485 return TRAVERSE_BREAK;
486 case TSE_R_LAYER:
489 return TRAVERSE_CONTINUE;
490 default:
492 }
493}
494
496{
497 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
498
500
501 outliner_tree_traverse(space_outliner,
502 &space_outliner->tree,
503 0,
506 &data);
507 return data.layer_collection;
508}
509
511{
512 Scene *scene = CTX_data_scene(C);
513 ViewLayer *view_layer = CTX_data_view_layer(C);
514 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
515 bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
516
517 IDsSelectedData selected_collections{};
518 outliner_tree_traverse(space_outliner,
519 &space_outliner->tree,
520 0,
523 &selected_collections);
524
525 if (selected_collections.selected_array.first == nullptr) {
526 return OPERATOR_CANCELLED;
527 }
528
529 LISTBASE_FOREACH (LinkData *, link, &selected_collections.selected_array) {
530 TreeElement *te = static_cast<TreeElement *>(link->data);
532 LayerCollection *layer_collection = static_cast<LayerCollection *>(te->directdata);
533 BKE_layer_collection_objects_select(scene, view_layer, layer_collection, deselect);
534 }
535 }
536
537 BLI_freelistN(&selected_collections.selected_array);
541
542 return OPERATOR_FINISHED;
543}
544
546{
547 /* identifiers */
548 ot->name = "Select Objects";
549 ot->idname = "OUTLINER_OT_collection_objects_select";
550 ot->description = "Select objects in collection";
551
552 /* api callbacks */
555
556 /* flags */
558}
559
561{
562 /* identifiers */
563 ot->name = "Deselect Objects";
564 ot->idname = "OUTLINER_OT_collection_objects_deselect";
565 ot->description = "Deselect objects in collection";
566
567 /* api callbacks */
570
571 /* flags */
573}
574
577/* -------------------------------------------------------------------- */
584
586 void *customdata)
587{
588 CollectionDuplicateData *data = static_cast<CollectionDuplicateData *>(customdata);
589 TreeStoreElem *tselem = TREESTORE(te);
590
591 switch (tselem->type) {
593 data->te = te;
594 return TRAVERSE_BREAK;
595 case TSE_R_LAYER:
598 default:
599 return TRAVERSE_CONTINUE;
600 }
601}
602
604{
605 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
606
607 CollectionDuplicateData data = {};
608
609 outliner_tree_traverse(space_outliner,
610 &space_outliner->tree,
611 0,
614 &data);
615 return data.te;
616}
617
619{
620 Main *bmain = CTX_data_main(C);
622 const bool linked = strstr(op->idname, "linked") != nullptr;
623
624 /* Can happen when calling from a key binding. */
625 if (te == nullptr) {
626 BKE_report(op->reports, RPT_ERROR, "No active collection");
627 return OPERATOR_CANCELLED;
628 }
629
631 Collection *parent = (te->parent) ? outliner_collection_from_tree_element(te->parent) : nullptr;
632 CollectionChild *child = BKE_collection_child_find(parent, collection);
633
634 /* We are allowed to duplicated linked collections (they will become local IDs then),
635 * but we should not allow its parent to be a linked ID, ever.
636 * This can happen when a whole scene is linked e.g. */
637 if (parent != nullptr && (!ID_IS_EDITABLE(parent) || ID_IS_OVERRIDE_LIBRARY(parent))) {
638 Scene *scene = CTX_data_scene(C);
639 parent = (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) ? nullptr :
640 scene->master_collection;
641 }
642 else if (parent != nullptr && (parent->flag & COLLECTION_IS_MASTER) != 0) {
644
645 Scene *scene_owner = reinterpret_cast<Scene *>(BKE_id_owner_get(&parent->id));
646 BLI_assert(scene_owner != nullptr);
647 BLI_assert(GS(scene_owner->id.name) == ID_SCE);
648
649 if (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
650 scene_owner = CTX_data_scene(C);
651 parent = (!ID_IS_EDITABLE(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) ?
652 nullptr :
653 scene_owner->master_collection;
654 }
655 }
656
657 if (collection->flag & COLLECTION_IS_MASTER) {
658 BKE_report(op->reports, RPT_ERROR, "Can't duplicate the master collection");
659 return OPERATOR_CANCELLED;
660 }
661
662 if (parent == nullptr) {
665 "Could not find a valid parent collection for the new duplicate, "
666 "it won't be linked to any view layer");
667 }
668
669 const eDupli_ID_Flags dupli_flags = (eDupli_ID_Flags)(USER_DUP_OBJECT |
670 (linked ? 0 : U.dupflag));
672 bmain, parent, child, collection, dupli_flags, LIB_ID_DUPLICATE_IS_ROOT_ID);
673
677
678 return OPERATOR_FINISHED;
679}
680
682{
683 /* identifiers */
684 ot->name = "Duplicate Linked Collection";
685 ot->idname = "OUTLINER_OT_collection_duplicate_linked";
686 ot->description =
687 "Recursively duplicate the collection, all its children and objects, with linked object "
688 "data";
689
690 /* api callbacks */
693
694 /* flags */
696}
697
699{
700 /* identifiers */
701 ot->name = "Duplicate Collection";
702 ot->idname = "OUTLINER_OT_collection_duplicate";
703 ot->description =
704 "Recursively duplicate the collection, all its children, objects and object data";
705
706 /* api callbacks */
709
710 /* flags */
712}
713
716/* -------------------------------------------------------------------- */
721{
722 Main *bmain = CTX_data_main(C);
723 Scene *scene = CTX_data_scene(C);
724 Collection *active_collection = CTX_data_layer_collection(C)->collection;
725 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
726
727 CollectionEditData data{};
728 data.scene = scene;
729 data.space_outliner = space_outliner;
730 data.is_liboverride_allowed = false; /* No linking of non-root collections. */
731 data.is_liboverride_hierarchy_root_allowed = true;
732
733 if ((!ID_IS_EDITABLE(active_collection) || ID_IS_OVERRIDE_LIBRARY(active_collection)) ||
734 ((active_collection->flag & COLLECTION_IS_MASTER) &&
735 (!ID_IS_EDITABLE(scene) || ID_IS_OVERRIDE_LIBRARY(scene))))
736 {
738 op->reports, RPT_ERROR, "Cannot add a collection to a linked/override collection/scene");
739 return OPERATOR_CANCELLED;
740 }
741
742 data.collections_to_edit = BLI_gset_ptr_new(__func__);
743
744 /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */
745 outliner_tree_traverse(space_outliner,
746 &space_outliner->tree,
747 0,
750 &data);
751
752 /* Effectively link the collections. */
753 GSetIterator collections_to_edit_iter;
754 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
755 Collection *collection = static_cast<Collection *>(
756 BLI_gsetIterator_getKey(&collections_to_edit_iter));
757 BKE_collection_child_add(bmain, active_collection, collection);
758 id_fake_user_clear(&collection->id);
759 }
760
761 BLI_gset_free(data.collections_to_edit, nullptr);
762
763 DEG_id_tag_update(&active_collection->id, ID_RECALC_SYNC_TO_EVAL);
765
767
768 return OPERATOR_FINISHED;
769}
770
772{
773 /* identifiers */
774 ot->name = "Link Collection";
775 ot->idname = "OUTLINER_OT_collection_link";
776 ot->description = "Link selected collections to active scene";
777
778 /* api callbacks */
781
782 /* flags */
784}
785
788/* -------------------------------------------------------------------- */
793{
794 Main *bmain = CTX_data_main(C);
795 Scene *scene = CTX_data_scene(C);
796 ViewLayer *view_layer = CTX_data_view_layer(C);
797 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
798 CollectionEditData data{};
799 data.scene = scene;
800 data.space_outliner = space_outliner;
801 data.is_liboverride_allowed = true;
802 data.is_liboverride_hierarchy_root_allowed = true;
803
804 data.collections_to_edit = BLI_gset_ptr_new(__func__);
805
806 /* We first walk over and find the Collections we actually want to instance
807 * (ignoring duplicates). */
808 outliner_tree_traverse(space_outliner,
809 &space_outliner->tree,
810 0,
813 &data);
814
815 /* Find an active collection to add to, that doesn't give dependency cycles. */
816 LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
817
818 GSetIterator collections_to_edit_iter;
819 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
820 Collection *collection = static_cast<Collection *>(
821 BLI_gsetIterator_getKey(&collections_to_edit_iter));
822
823 while (BKE_collection_cycle_find(active_lc->collection, collection)) {
824 active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
825 }
826 }
827
828 /* Effectively instance the collections. */
829 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
830 Collection *collection = static_cast<Collection *>(
831 BLI_gsetIterator_getKey(&collections_to_edit_iter));
833 C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, nullptr, false, 0);
834 ob->instance_collection = collection;
836 id_us_plus(&collection->id);
837 }
838
839 BLI_gset_free(data.collections_to_edit, nullptr);
840
842
844
845 return OPERATOR_FINISHED;
846}
847
849{
850 /* identifiers */
851 ot->name = "Instance Collection";
852 ot->idname = "OUTLINER_OT_collection_instance";
853 ot->description = "Instance selected collections to active scene";
854
855 /* api callbacks */
858
859 /* flags */
861}
862
865/* -------------------------------------------------------------------- */
870{
871 CollectionEditData *data = static_cast<CollectionEditData *>(customdata);
872 TreeStoreElem *tselem = TREESTORE(te);
873
874 if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
875 return TRAVERSE_CONTINUE;
876 }
877
878 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
879
881 /* skip - showing warning/error message might be misleading
882 * when deleting multiple collections, so just do nothing */
883 }
884 else {
885 /* Delete, duplicate and link don't edit children, those will come along
886 * with the parents. */
887 BLI_gset_add(data->collections_to_edit, lc);
888 }
889
890 return TRAVERSE_CONTINUE;
891}
892
894{
895 /* Poll function so the right click menu show current state of selected collections. */
896 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
897 if (!(space_outliner && space_outliner->outlinevis == SO_VIEW_LAYER)) {
898 return false;
899 }
900
901 Scene *scene = CTX_data_scene(C);
902 CollectionEditData data{};
903 data.scene = scene;
904 data.space_outliner = space_outliner;
905 data.is_liboverride_allowed = true;
906 data.is_liboverride_hierarchy_root_allowed = true;
907 data.collections_to_edit = BLI_gset_ptr_new(__func__);
908 bool result = false;
909
910 outliner_tree_traverse(space_outliner,
911 &space_outliner->tree,
912 0,
915 &data);
916
917 GSetIterator collections_to_edit_iter;
918 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
919 LayerCollection *lc = static_cast<LayerCollection *>(
920 BLI_gsetIterator_getKey(&collections_to_edit_iter));
921
922 if (clear && (lc->flag & flag)) {
923 result = true;
924 }
925 else if (!clear && !(lc->flag & flag)) {
926 result = true;
927 }
928 }
929
930 BLI_gset_free(data.collections_to_edit, nullptr);
931 return result;
932}
933
938
943
948
953
958
963
965{
966 Main *bmain = CTX_data_main(C);
967 Scene *scene = CTX_data_scene(C);
968 ViewLayer *view_layer = CTX_data_view_layer(C);
969 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
970 CollectionEditData data{};
971 data.scene = scene;
972 data.space_outliner = space_outliner;
973 data.is_liboverride_allowed = true;
974 data.is_liboverride_hierarchy_root_allowed = true;
975 bool clear = strstr(op->idname, "clear") != nullptr;
976 int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
977 strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
979
980 data.collections_to_edit = BLI_gset_ptr_new(__func__);
981
982 outliner_tree_traverse(space_outliner,
983 &space_outliner->tree,
984 0,
987 &data);
988
989 GSetIterator collections_to_edit_iter;
990 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
991 LayerCollection *lc = static_cast<LayerCollection *>(
992 BLI_gsetIterator_getKey(&collections_to_edit_iter));
994 }
995
996 BLI_gset_free(data.collections_to_edit, nullptr);
997
1000
1002
1003 return OPERATOR_FINISHED;
1004}
1005
1007{
1008 /* identifiers */
1009 ot->name = "Disable from View Layer";
1010 ot->idname = "OUTLINER_OT_collection_exclude_set";
1011 ot->description = "Exclude collection from the active view layer";
1012
1013 /* api callbacks */
1016
1017 /* flags */
1019}
1020
1022{
1023 /* identifiers */
1024 ot->name = "Enable in View Layer";
1025 ot->idname = "OUTLINER_OT_collection_exclude_clear";
1026 ot->description = "Include collection in the active view layer";
1027
1028 /* api callbacks */
1031
1032 /* flags */
1034}
1035
1037{
1038 /* identifiers */
1039 ot->name = "Set Holdout";
1040 ot->idname = "OUTLINER_OT_collection_holdout_set";
1041 ot->description = "Mask collection in the active view layer";
1042
1043 /* api callbacks */
1046
1047 /* flags */
1049}
1050
1052{
1053 /* identifiers */
1054 ot->name = "Clear Holdout";
1055 ot->idname = "OUTLINER_OT_collection_holdout_clear";
1056 ot->description = "Clear masking of collection in the active view layer";
1057
1058 /* api callbacks */
1061
1062 /* flags */
1064}
1065
1067{
1068 /* identifiers */
1069 ot->name = "Set Indirect Only";
1070 ot->idname = "OUTLINER_OT_collection_indirect_only_set";
1071 ot->description =
1072 "Set collection to only contribute indirectly (through shadows and reflections) in the view "
1073 "layer";
1074
1075 /* api callbacks */
1078
1079 /* flags */
1081}
1082
1084{
1085 /* identifiers */
1086 ot->name = "Clear Indirect Only";
1087 ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
1088 ot->description = "Clear collection contributing only indirectly in the view layer";
1089
1090 /* api callbacks */
1093
1094 /* flags */
1096}
1097
1100/* -------------------------------------------------------------------- */
1105{
1106 Scene *scene = CTX_data_scene(C);
1107 ViewLayer *view_layer = CTX_data_view_layer(C);
1108 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1109 const bool extend = RNA_boolean_get(op->ptr, "extend");
1110 CollectionEditData data{};
1111 data.scene = scene;
1112 data.space_outliner = space_outliner;
1113 data.is_liboverride_allowed = true;
1114 data.is_liboverride_hierarchy_root_allowed = true;
1115 data.collections_to_edit = BLI_gset_ptr_new(__func__);
1116 outliner_tree_traverse(space_outliner,
1117 &space_outliner->tree,
1118 0,
1121 &data);
1122
1123 GSetIterator collections_to_edit_iter;
1124 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1125 LayerCollection *layer_collection = static_cast<LayerCollection *>(
1126 BLI_gsetIterator_getKey(&collections_to_edit_iter));
1127
1128 if (extend) {
1129 BKE_layer_collection_isolate_global(scene, view_layer, layer_collection, true);
1130 }
1131 else {
1132 PropertyRNA *prop = RNA_struct_type_find_property(&RNA_LayerCollection, "hide_viewport");
1133 PointerRNA ptr = RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection);
1134
1135 /* We need to flip the value because the isolate flag routine was designed to work from the
1136 * outliner as a callback. That means the collection visibility was set before the callback
1137 * was called. */
1138 const bool value = !RNA_property_boolean_get(&ptr, prop);
1140 scene, view_layer, layer_collection, nullptr, prop, "hide_viewport", value);
1141 break;
1142 }
1143 }
1144 BLI_gset_free(data.collections_to_edit, nullptr);
1145
1148
1150 return OPERATOR_FINISHED;
1151}
1152
1153static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1154{
1155 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
1156 if (!RNA_property_is_set(op->ptr, prop) && (event->modifier & KM_SHIFT)) {
1157 RNA_property_boolean_set(op->ptr, prop, true);
1158 }
1159 return collection_isolate_exec(C, op);
1160}
1161
1163{
1164 /* identifiers */
1165 ot->name = "Isolate Collection";
1166 ot->idname = "OUTLINER_OT_collection_isolate";
1167 ot->description = "Hide all but this collection and its parents";
1168
1169 /* api callbacks */
1173
1174 /* flags */
1176
1177 /* properties */
1179 ot->srna, "extend", false, "Extend", "Extend current visible collections");
1181}
1182
1184{
1186}
1187
1189{
1191}
1192
1194{
1196 return false;
1197 }
1198 return outliner_active_layer_collection(C) != nullptr;
1199}
1200
1202{
1203 Scene *scene = CTX_data_scene(C);
1204 ViewLayer *view_layer = CTX_data_view_layer(C);
1205 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1206 const bool is_inside = strstr(op->idname, "inside") != nullptr;
1207 const bool show = strstr(op->idname, "show") != nullptr;
1208 CollectionEditData data{};
1209 data.scene = scene;
1210 data.space_outliner = space_outliner;
1211 data.is_liboverride_allowed = true;
1212 data.is_liboverride_hierarchy_root_allowed = true;
1213 data.collections_to_edit = BLI_gset_ptr_new(__func__);
1214
1215 outliner_tree_traverse(space_outliner,
1216 &space_outliner->tree,
1217 0,
1220 &data);
1221
1222 GSetIterator collections_to_edit_iter;
1223 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1224 LayerCollection *layer_collection = static_cast<LayerCollection *>(
1225 BLI_gsetIterator_getKey(&collections_to_edit_iter));
1226 BKE_layer_collection_set_visible(scene, view_layer, layer_collection, show, is_inside);
1227 }
1228 BLI_gset_free(data.collections_to_edit, nullptr);
1229
1232
1234 return OPERATOR_FINISHED;
1235}
1236
1238{
1239 /* identifiers */
1240 ot->name = "Show Collection";
1241 ot->idname = "OUTLINER_OT_collection_show";
1242 ot->description = "Show the collection in this view layer";
1243
1244 /* api callbacks */
1247
1248 /* flags */
1250}
1251
1253{
1254 /* identifiers */
1255 ot->name = "Hide Collection";
1256 ot->idname = "OUTLINER_OT_collection_hide";
1257 ot->description = "Hide the collection in this view layer";
1258
1259 /* api callbacks */
1262
1263 /* flags */
1265}
1266
1268{
1269 /* identifiers */
1270 ot->name = "Show Inside Collection";
1271 ot->idname = "OUTLINER_OT_collection_show_inside";
1272 ot->description = "Show all the objects and collections inside the collection";
1273
1274 /* api callbacks */
1277
1278 /* flags */
1280}
1281
1283{
1284 /* identifiers */
1285 ot->name = "Hide Inside Collection";
1286 ot->idname = "OUTLINER_OT_collection_hide_inside";
1287 ot->description = "Hide all the objects and collections inside the collection";
1288
1289 /* api callbacks */
1292
1293 /* flags */
1295}
1296
1299/* -------------------------------------------------------------------- */
1303static bool collection_flag_poll(bContext *C, bool clear, int flag)
1304{
1306 return false;
1307 }
1308
1310 if (te == nullptr) {
1311 return false;
1312 }
1313
1315 if (collection == nullptr) {
1316 return false;
1317 }
1318
1319 if (clear && (collection->flag & flag)) {
1320 return true;
1321 }
1322 if (!clear && !(collection->flag & flag)) {
1323 return true;
1324 }
1325
1326 return false;
1327}
1328
1330{
1332}
1333
1335{
1337}
1338
1343
1348
1350{
1351 Main *bmain = CTX_data_main(C);
1352 Scene *scene = CTX_data_scene(C);
1353 ViewLayer *view_layer = CTX_data_view_layer(C);
1354 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1355 const bool is_render = strstr(op->idname, "render");
1356 const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
1358 CollectionEditData data{};
1359 data.scene = scene;
1360 data.space_outliner = space_outliner;
1361 data.is_liboverride_allowed = true;
1362 data.is_liboverride_hierarchy_root_allowed = true;
1363 data.collections_to_edit = BLI_gset_ptr_new(__func__);
1364 const bool has_layer_collection = space_outliner->outlinevis == SO_VIEW_LAYER;
1365
1366 if (has_layer_collection) {
1367 outliner_tree_traverse(space_outliner,
1368 &space_outliner->tree,
1369 0,
1372 &data);
1373 GSetIterator collections_to_edit_iter;
1374 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1375 LayerCollection *layer_collection = static_cast<LayerCollection *>(
1376 BLI_gsetIterator_getKey(&collections_to_edit_iter));
1377 Collection *collection = layer_collection->collection;
1378 if (!BKE_id_is_editable(bmain, &collection->id)) {
1379 continue;
1380 }
1381 if (clear) {
1382 collection->flag &= ~flag;
1383 }
1384 else {
1385 collection->flag |= flag;
1386 }
1387
1388 /* Make sure (at least for this view layer) the collection is visible. */
1389 if (clear && !is_render) {
1390 layer_collection->flag &= ~LAYER_COLLECTION_HIDE;
1391 }
1392 }
1393 BLI_gset_free(data.collections_to_edit, nullptr);
1394 }
1395 else {
1396 outliner_tree_traverse(space_outliner,
1397 &space_outliner->tree,
1398 0,
1401 &data);
1402 GSetIterator collections_to_edit_iter;
1403 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1404 Collection *collection = static_cast<Collection *>(
1405 BLI_gsetIterator_getKey(&collections_to_edit_iter));
1406 if (!BKE_id_is_editable(bmain, &collection->id)) {
1407 continue;
1408 }
1409
1410 if (clear) {
1411 collection->flag &= ~flag;
1412 }
1413 else {
1414 collection->flag |= flag;
1415 }
1416 }
1417 BLI_gset_free(data.collections_to_edit, nullptr);
1418 }
1419
1422
1423 if (!is_render) {
1425 }
1426
1428 return OPERATOR_FINISHED;
1429}
1430
1432{
1433 /* identifiers */
1434 ot->name = "Enable Collection";
1435 ot->idname = "OUTLINER_OT_collection_enable";
1436 ot->description = "Enable viewport display in the view layers";
1437
1438 /* api callbacks */
1441
1442 /* flags */
1444}
1445
1447{
1448 /* identifiers */
1449 ot->name = "Disable Collection";
1450 ot->idname = "OUTLINER_OT_collection_disable";
1451 ot->description = "Disable viewport display in the view layers";
1452
1453 /* api callbacks */
1456
1457 /* flags */
1459}
1460
1462{
1463 /* identifiers */
1464 ot->name = "Enable Collection in Render";
1465 ot->idname = "OUTLINER_OT_collection_enable_render";
1466 ot->description = "Render the collection";
1467
1468 /* api callbacks */
1471
1472 /* flags */
1474}
1475
1477{
1478 /* identifiers */
1479 ot->name = "Disable Collection in Render";
1480 ot->idname = "OUTLINER_OT_collection_disable_render";
1481 ot->description = "Do not render this collection";
1482
1483 /* api callbacks */
1486
1487 /* flags */
1489}
1490
1498
1501/* -------------------------------------------------------------------- */
1506{
1507 OutlinerHideEditData *data = static_cast<OutlinerHideEditData *>(customdata);
1508 TreeStoreElem *tselem = TREESTORE(te);
1509
1510 if (tselem == nullptr) {
1511 return TRAVERSE_CONTINUE;
1512 }
1513
1514 if (tselem->type == TSE_LAYER_COLLECTION) {
1515 LayerCollection *lc = static_cast<LayerCollection *>(te->directdata);
1516
1518 /* Skip - showing warning/error message might be misleading
1519 * when deleting multiple collections, so just do nothing. */
1520 }
1521 else {
1522 /* Delete, duplicate and link don't edit children,
1523 * those will come along with the parents. */
1524 BLI_gset_add(data->collections_to_edit, lc);
1525 }
1526 }
1527 else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1528 Object *ob = (Object *)tselem->id;
1529 BKE_view_layer_synced_ensure(data->scene, data->view_layer);
1530 Base *base = BKE_view_layer_base_find(data->view_layer, ob);
1531 BLI_gset_add(data->bases_to_edit, base);
1532 }
1533
1534 return TRAVERSE_CONTINUE;
1535}
1536
1538{
1539 Scene *scene = CTX_data_scene(C);
1540 ViewLayer *view_layer = CTX_data_view_layer(C);
1541 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1542 OutlinerHideEditData data{};
1543 data.scene = scene;
1544 data.view_layer = view_layer;
1545 data.space_outliner = space_outliner;
1546 data.collections_to_edit = BLI_gset_ptr_new("outliner_hide_exec__collections_to_edit");
1547 data.bases_to_edit = BLI_gset_ptr_new("outliner_hide_exec__bases_to_edit");
1548
1549 outliner_tree_traverse(space_outliner,
1550 &space_outliner->tree,
1551 0,
1554 &data);
1555
1556 GSetIterator collections_to_edit_iter;
1557 GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1558 LayerCollection *layer_collection = static_cast<LayerCollection *>(
1559 BLI_gsetIterator_getKey(&collections_to_edit_iter));
1560 BKE_layer_collection_set_visible(scene, view_layer, layer_collection, false, false);
1561 }
1562 BLI_gset_free(data.collections_to_edit, nullptr);
1563
1564 GSetIterator bases_to_edit_iter;
1565 GSET_ITER (bases_to_edit_iter, data.bases_to_edit) {
1566 Base *base = static_cast<Base *>(BLI_gsetIterator_getKey(&bases_to_edit_iter));
1567 base->flag |= BASE_HIDDEN;
1568 }
1569 BLI_gset_free(data.bases_to_edit, nullptr);
1570
1573
1575 return OPERATOR_FINISHED;
1576}
1577
1579{
1580 /* identifiers */
1581 ot->name = "Hide";
1582 ot->idname = "OUTLINER_OT_hide";
1583 ot->description = "Hide selected objects and collections";
1584
1585 /* api callbacks */
1588
1589 /* flags */
1591}
1592
1594{
1595 Scene *scene = CTX_data_scene(C);
1596 ViewLayer *view_layer = CTX_data_view_layer(C);
1597
1598 /* Unhide all the collections. */
1599 LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first);
1600 LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1602 }
1603
1604 /* Unhide all objects. */
1605 BKE_view_layer_synced_ensure(scene, view_layer);
1607 base->flag &= ~BASE_HIDDEN;
1608 }
1609
1612
1614 return OPERATOR_FINISHED;
1615}
1616
1618{
1619 /* identifiers */
1620 ot->name = "Unhide All";
1621 ot->idname = "OUTLINER_OT_unhide_all";
1622 ot->description = "Unhide all objects and collections";
1623
1624 /* api callbacks */
1627
1628 /* flags */
1630}
1631
1634/* -------------------------------------------------------------------- */
1639{
1640 Scene *scene = CTX_data_scene(C);
1641 SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1642 const short color_tag = RNA_enum_get(op->ptr, "color");
1643
1644 IDsSelectedData selected{};
1645
1646 outliner_tree_traverse(space_outliner,
1647 &space_outliner->tree,
1648 0,
1651 &selected);
1652
1653 LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
1654 TreeElement *te_selected = (TreeElement *)link->data;
1655
1656 Collection *collection = outliner_collection_from_tree_element(te_selected);
1657 if (collection == scene->master_collection) {
1658 continue;
1659 }
1660 if (!BKE_id_is_editable(CTX_data_main(C), &collection->id)) {
1661 BKE_report(op->reports, RPT_WARNING, "Can't add a color tag to a linked collection");
1662 continue;
1663 }
1664
1665 collection->color_tag = color_tag;
1666 };
1667
1668 BLI_freelistN(&selected.selected_array);
1669
1671
1672 return OPERATOR_FINISHED;
1673}
1674
1676{
1677 /* identifiers */
1678 ot->name = "Set Color Tag";
1679 ot->idname = "OUTLINER_OT_collection_color_tag_set";
1680 ot->description = "Set a color tag for the selected collections";
1681
1682 /* api callbacks */
1685
1686 /* flags */
1688
1690 ot->srna, "color", rna_enum_collection_color_items, COLLECTION_COLOR_NONE, "Color Tag", "");
1691}
1692
1695} // 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)
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)
Collection * BKE_collection_duplicate(Main *bmain, Collection *parent, CollectionChild *child_old, Collection *collection, uint duplicate_flags, uint duplicate_options)
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:2456
void id_us_plus(ID *id)
Definition lib_id.cc:351
ID * BKE_id_owner_get(ID *id, const bool debug_relationship_assert=true)
Definition lib_id.cc:2444
void id_fake_user_clear(ID *id)
Definition lib_id.cc:397
@ 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:125
#define BLI_assert(a)
Definition BLI_assert.h:50
struct GSet GSet
Definition BLI_ghash.h:341
GSet * BLI_gset_ptr_new(const char *info)
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition BLI_ghash.h:459
#define GSET_ITER(gs_iter_, gset_)
Definition BLI_ghash.h:472
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition BLI_ghash.c:1034
bool BLI_gset_add(GSet *gs, void *key)
Definition BLI_ghash.c:966
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
struct LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:909
#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_RECALC_SELECT
Definition DNA_ID.h:1068
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ ID_RECALC_BASE_FLAGS
Definition DNA_ID.h:1071
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition DNA_ID.h:676
#define ID_IS_EDITABLE(_id)
Definition DNA_ID.h:658
@ ID_FLAG_EMBEDDED_DATA
Definition DNA_ID.h:725
@ ID_TAG_INDIRECT
Definition DNA_ID.h:794
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
#define ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(_id)
Definition DNA_ID.h:686
@ 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
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:245
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define ND_OB_SELECT
Definition WM_types.hh:409
#define NC_SCENE
Definition WM_types.hh:345
#define ND_LAYER_CONTENT
Definition WM_types.hh:420
#define ND_LAYER
Definition WM_types.hh:417
@ KM_SHIFT
Definition WM_types.hh:255
unsigned int U
Definition btGjkEpa3.h:78
static bool is_inside(int x, int y, int cols, int rows)
Definition filesel.cc:768
#define GS(x)
Definition iris.cc:202
static void clear(Message &msg)
Definition msgfmt.cc:218
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
static int collection_link_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_duplicate_linked(wmOperatorType *ot)
static int outliner_hide_exec(bContext *C, wmOperator *)
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 bool collections_holdout_clear_poll(bContext *C)
bool outliner_is_collection_tree_element(const TreeElement *te)
static TreeElement * outliner_active_collection(bContext *C)
static bool collection_disable_poll(bContext *C)
static int collection_view_layer_exec(bContext *C, wmOperator *op)
static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata)
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 int collection_instance_exec(bContext *C, wmOperator *)
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)
void outliner_collection_delete(bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
static bool collection_enable_poll(bContext *C)
static int collection_hierarchy_delete_exec(bContext *C, wmOperator *op)
void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, SpaceOutliner *space_outliner, ARegion *region)
static int outliner_unhide_all_exec(bContext *C, wmOperator *)
static bool collections_holdout_set_poll(bContext *C)
void OUTLINER_OT_unhide_all(wmOperatorType *ot)
void OUTLINER_OT_collection_hide_inside(wmOperatorType *ot)
static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void OUTLINER_OT_collection_enable(wmOperatorType *ot)
static bool outliner_view_layer_collections_editor_poll(bContext *C)
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)
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 int collection_new_exec(bContext *C, wmOperator *op)
static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void *customdata)
static TreeTraversalAction outliner_hide_collect_data_to_edit(TreeElement *te, void *customdata)
static int collection_isolate_exec(bContext *C, wmOperator *op)
static bool collection_disable_render_poll(bContext *C)
static int outliner_color_tag_set_exec(bContext *C, wmOperator *op)
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 int collection_duplicate_exec(bContext *C, wmOperator *op)
static int collection_visibility_exec(bContext *C, wmOperator *op)
static bool collection_flag_poll(bContext *C, bool clear, int flag)
static bool collection_enable_render_poll(bContext *C)
static int collection_flag_exec(bContext *C, wmOperator *op)
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)
void OUTLINER_OT_collection_enable_render(wmOperatorType *ot)
static int collection_objects_select_exec(bContext *C, wmOperator *op)
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(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
Definition DNA_ID.h:413
short flag
Definition DNA_ID.h:430
char name[66]
Definition DNA_ID.h:425
ListBase layer_collections
struct Collection * collection
void * first
ListBase collections
Definition BKE_main.hh:231
short transflag
struct Collection * instance_collection
struct Collection * master_collection
ListBase layer_collections
uint8_t modifier
Definition WM_types.hh:739
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
StructRNA * srna
Definition WM_types.hh:1080
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:4126
wmOperatorType * ot
Definition wm_files.cc:4125
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)
uint8_t flag
Definition wm_window.cc:138