Blender  V2.93
outliner_collections.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
21 #include <string.h>
22 
23 #include "BLI_listbase.h"
24 #include "BLI_utildefines.h"
25 
26 #include "DNA_collection_types.h"
27 #include "DNA_object_types.h"
28 
29 #include "BKE_collection.h"
30 #include "BKE_context.h"
31 #include "BKE_idtype.h"
32 #include "BKE_layer.h"
33 #include "BKE_lib_id.h"
34 #include "BKE_main.h"
35 #include "BKE_report.h"
36 
37 #include "DEG_depsgraph.h"
38 #include "DEG_depsgraph_build.h"
39 
40 #include "ED_object.h"
41 #include "ED_outliner.h"
42 #include "ED_screen.h"
43 
44 #include "WM_api.h"
45 #include "WM_message.h"
46 #include "WM_types.h"
47 
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50 #include "RNA_enum_types.h"
51 
52 #include "outliner_intern.h" /* own include */
53 
54 /* -------------------------------------------------------------------- */
59 {
60  TreeStoreElem *tselem = TREESTORE(te);
61 
62  if (!tselem) {
63  return false;
64  }
65 
66  if (ELEM(tselem->type,
70  return true;
71  }
72  if ((tselem->type == TSE_SOME_ID) && te->idcode == ID_GR) {
73  return true;
74  }
75 
76  return false;
77 }
78 
80 {
81  TreeStoreElem *tselem = TREESTORE(te);
82 
83  if (!tselem) {
84  return NULL;
85  }
86 
87  if (tselem->type == TSE_LAYER_COLLECTION) {
88  LayerCollection *lc = te->directdata;
89  return lc->collection;
90  }
92  Scene *scene = (Scene *)tselem->id;
93  return scene->master_collection;
94  }
95  if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_GR)) {
96  return (Collection *)tselem->id;
97  }
98 
99  return NULL;
100 }
101 
103 {
104  struct IDsSelectedData *data = customdata;
105  TreeStoreElem *tselem = TREESTORE(te);
106 
108  BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
109  return TRAVERSE_CONTINUE;
110  }
111 
112  if ((tselem->type != TSE_SOME_ID) || (tselem->id && GS(tselem->id->name) != ID_GR)) {
113  return TRAVERSE_SKIP_CHILDS;
114  }
115 
116  return TRAVERSE_CONTINUE;
117 }
118 
120 {
121  struct IDsSelectedData *data = customdata;
122  TreeStoreElem *tselem = TREESTORE(te);
123 
125  return TRAVERSE_CONTINUE;
126  }
127 
128  if ((tselem->type != TSE_SOME_ID) || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) {
129  return TRAVERSE_SKIP_CHILDS;
130  }
131 
132  BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
133 
134  return TRAVERSE_CONTINUE;
135 }
136 
143 {
144  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
145  struct IDsSelectedData data = {{NULL}};
146  outliner_tree_traverse(space_outliner,
147  &space_outliner->tree,
148  0,
149  TSE_SELECTED,
151  &data);
152  LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
153  TreeElement *ten_selected = (TreeElement *)link->data;
154  Object *ob = (Object *)TREESTORE(ten_selected)->id;
155  BLI_addtail(objects, BLI_genericNodeN(ob));
156  }
157  BLI_freelistN(&data.selected_array);
158 }
159 
162 /* -------------------------------------------------------------------- */
167 {
168  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
169  return (space_outliner != NULL) &&
170  ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES, SO_LIBRARIES);
171 }
172 
174 {
175  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
176  return (space_outliner != NULL) && (space_outliner->outlinevis == SO_VIEW_LAYER);
177 }
178 
180 {
182  return false;
183  }
186  return false;
187  }
188  return true;
189 }
190 
193 /* -------------------------------------------------------------------- */
198  bool error;
200 };
201 
203 {
204  struct CollectionNewData *data = customdata;
206 
207  if (!collection) {
208  return TRAVERSE_SKIP_CHILDS;
209  }
210 
211  if (data->collection != NULL) {
212  data->error = true;
213  return TRAVERSE_BREAK;
214  }
215 
216  data->collection = collection;
217  return TRAVERSE_CONTINUE;
218 }
219 
221 {
222  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
223  ARegion *region = CTX_wm_region(C);
224  Main *bmain = CTX_data_main(C);
226  ViewLayer *view_layer = CTX_data_view_layer(C);
227 
228  struct CollectionNewData data = {
229  .error = false,
230  .collection = NULL,
231  };
232 
233  if (RNA_boolean_get(op->ptr, "nested")) {
234  outliner_build_tree(bmain, scene, view_layer, space_outliner, region);
235 
236  outliner_tree_traverse(space_outliner,
237  &space_outliner->tree,
238  0,
239  TSE_SELECTED,
241  &data);
242 
243  if (data.error) {
244  BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
245  return OPERATOR_CANCELLED;
246  }
247  }
248 
249  if (data.collection == NULL || ID_IS_LINKED(data.collection) ||
250  ID_IS_OVERRIDE_LIBRARY(data.collection)) {
251  data.collection = scene->master_collection;
252  }
253 
255  BKE_report(op->reports, RPT_ERROR, "Can't add a new collection to linked/override scene");
256  return OPERATOR_CANCELLED;
257  }
258 
259  BKE_collection_add(bmain, data.collection, NULL);
260 
263 
264  outliner_cleanup_tree(space_outliner);
266  return OPERATOR_FINISHED;
267 }
268 
270 {
271  /* identifiers */
272  ot->name = "New Collection";
273  ot->idname = "OUTLINER_OT_collection_new";
274  ot->description = "Add a new collection inside selected collection";
275 
276  /* api callbacks */
279 
280  /* flags */
282 
283  /* properties */
285  ot->srna, "nested", true, "Nested", "Add as child of selected collection");
287 }
288 
291 /* -------------------------------------------------------------------- */
299 };
300 
302 {
303  struct CollectionEditData *data = customdata;
305 
306  if (!collection) {
307  return TRAVERSE_SKIP_CHILDS;
308  }
309 
310  if (collection->flag & COLLECTION_IS_MASTER) {
311  /* skip - showing warning/error message might be misleading
312  * when deleting multiple collections, so just do nothing */
313  }
314  else {
315  /* Delete, duplicate and link don't edit children, those will come along
316  * with the parents. */
317  BLI_gset_add(data->collections_to_edit, collection);
318  return TRAVERSE_SKIP_CHILDS;
319  }
320 
321  return TRAVERSE_CONTINUE;
322 }
323 
325  bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool hierarchy)
326 {
328 
329  struct CollectionEditData data = {
330  .scene = scene,
331  .space_outliner = space_outliner,
332  };
333 
334  data.collections_to_edit = BLI_gset_ptr_new(__func__);
335 
336  /* We first walk over and find the Collections we actually want to delete
337  * (ignoring duplicates). */
340 
341  /* Effectively delete the collections. */
342  GSetIterator collections_to_edit_iter;
343  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
344  Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
345 
346  /* Test in case collection got deleted as part of another one. */
347  if (BLI_findindex(&bmain->collections, collection) != -1) {
348  /* We cannot allow deleting collections that are indirectly linked,
349  * or that are used by (linked to...) other linked scene/collection. */
350  bool skip = false;
351  if (ID_IS_LINKED(collection)) {
352  if (collection->id.tag & LIB_TAG_INDIRECT) {
353  skip = true;
354  }
355  else {
356  LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
357  Collection *parent = cparent->collection;
358  if (ID_IS_LINKED(parent)) {
359  skip = true;
360  break;
361  }
362  if (parent->flag & COLLECTION_IS_MASTER) {
363  BLI_assert(parent->id.flag & LIB_EMBEDDED_DATA);
364 
365  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(&parent->id);
366  BLI_assert(id_type->owner_get != NULL);
367 
368  ID *scene_owner = id_type->owner_get(bmain, &parent->id);
369  BLI_assert(GS(scene_owner->name) == ID_SCE);
370  if (ID_IS_LINKED(scene_owner)) {
371  skip = true;
372  break;
373  }
374  }
375  }
376  }
377  }
378 
379  if (!skip) {
380  BKE_collection_delete(bmain, collection, hierarchy);
381  }
382  else {
383  BKE_reportf(
384  reports,
385  RPT_WARNING,
386  "Cannot delete linked collection '%s', it is used by other linked scenes/collections",
387  collection->id.name + 2);
388  }
389  }
390  }
391 
392  BLI_gset_free(data.collections_to_edit, NULL);
393 }
394 
396 {
397  Main *bmain = CTX_data_main(C);
399  ViewLayer *view_layer = CTX_data_view_layer(C);
400  struct wmMsgBus *mbus = CTX_wm_message_bus(C);
401  const Base *basact_prev = BASACT(view_layer);
402 
403  outliner_collection_delete(C, bmain, scene, op->reports, true);
404 
407 
409 
410  if (basact_prev != BASACT(view_layer)) {
411  WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
412  }
413 
415 
416  return OPERATOR_FINISHED;
417 }
418 
420 {
421  /* identifiers */
422  ot->name = "Delete Hierarchy";
423  ot->idname = "OUTLINER_OT_collection_hierarchy_delete";
424  ot->description = "Delete selected collection hierarchies";
425 
426  /* api callbacks */
429 
430  /* flags */
432 }
433 
436 /* -------------------------------------------------------------------- */
441  bool error;
443 };
444 
446  void *customdata)
447 {
448  struct CollectionObjectsSelectData *data = customdata;
449  TreeStoreElem *tselem = TREESTORE(te);
450 
451  switch (tselem->type) {
453  data->layer_collection = te->directdata;
454  return TRAVERSE_BREAK;
455  case TSE_R_LAYER:
458  return TRAVERSE_CONTINUE;
459  default:
460  return TRAVERSE_SKIP_CHILDS;
461  }
462 }
463 
465 {
466  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
467 
469  .layer_collection = NULL,
470  };
471 
472  outliner_tree_traverse(space_outliner,
473  &space_outliner->tree,
474  0,
475  TSE_SELECTED,
477  &data);
478  return data.layer_collection;
479 }
480 
482 {
483  ViewLayer *view_layer = CTX_data_view_layer(C);
485  bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
486 
487  if (layer_collection == NULL) {
488  return OPERATOR_CANCELLED;
489  }
490 
492 
497 
498  return OPERATOR_FINISHED;
499 }
500 
502 {
503  /* identifiers */
504  ot->name = "Select Objects";
505  ot->idname = "OUTLINER_OT_collection_objects_select";
506  ot->description = "Select objects in collection";
507 
508  /* api callbacks */
511 
512  /* flags */
514 }
515 
517 {
518  /* identifiers */
519  ot->name = "Deselect Objects";
520  ot->idname = "OUTLINER_OT_collection_objects_deselect";
521  ot->description = "Deselect objects in collection";
522 
523  /* api callbacks */
526 
527  /* flags */
529 }
530 
533 /* -------------------------------------------------------------------- */
539 };
540 
542  void *customdata)
543 {
544  struct CollectionDuplicateData *data = customdata;
545  TreeStoreElem *tselem = TREESTORE(te);
546 
547  switch (tselem->type) {
549  data->te = te;
550  return TRAVERSE_BREAK;
551  case TSE_R_LAYER:
554  default:
555  return TRAVERSE_CONTINUE;
556  }
557 }
558 
560 {
561  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
562 
563  struct CollectionDuplicateData data = {
564  .te = NULL,
565  };
566 
567  outliner_tree_traverse(space_outliner,
568  &space_outliner->tree,
569  0,
570  TSE_SELECTED,
572  &data);
573  return data.te;
574 }
575 
577 {
578  Main *bmain = CTX_data_main(C);
580  const bool linked = strstr(op->idname, "linked") != NULL;
581 
582  /* Can happen when calling from a key binding. */
583  if (te == NULL) {
584  BKE_report(op->reports, RPT_ERROR, "No active collection");
585  return OPERATOR_CANCELLED;
586  }
587 
590 
591  /* We are allowed to duplicated linked collections (they will become local IDs then),
592  * but we should not allow its parent to be a linked ID, ever.
593  * This can happen when a whole scene is linked e.g. */
594  if (parent != NULL && (ID_IS_LINKED(parent) || ID_IS_OVERRIDE_LIBRARY(parent))) {
598  }
599  else if (parent != NULL && (parent->flag & COLLECTION_IS_MASTER) != 0) {
600  BLI_assert(parent->id.flag & LIB_EMBEDDED_DATA);
601 
602  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(&parent->id);
603  BLI_assert(id_type->owner_get != NULL);
604 
605  Scene *scene_owner = (Scene *)id_type->owner_get(bmain, &parent->id);
606  BLI_assert(scene_owner != NULL);
607  BLI_assert(GS(scene_owner->id.name) == ID_SCE);
608 
609  if (ID_IS_LINKED(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
610  scene_owner = CTX_data_scene(C);
611  parent = ID_IS_LINKED(scene_owner) ? NULL : scene_owner->master_collection;
612  }
613  }
614 
615  if (collection->flag & COLLECTION_IS_MASTER) {
616  BKE_report(op->reports, RPT_ERROR, "Can't duplicate the master collection");
617  return OPERATOR_CANCELLED;
618  }
619 
620  if (parent == NULL) {
621  BKE_report(op->reports,
622  RPT_WARNING,
623  "Could not find a valid parent collection for the new duplicate, "
624  "it won't be linked to any view layer");
625  }
626 
627  const eDupli_ID_Flags dupli_flags = USER_DUP_OBJECT | (linked ? 0 : U.dupflag);
628  BKE_collection_duplicate(bmain, parent, collection, dupli_flags, LIB_ID_DUPLICATE_IS_ROOT_ID);
629 
633 
634  return OPERATOR_FINISHED;
635 }
636 
638 {
639  /* identifiers */
640  ot->name = "Duplicate Linked Collection";
641  ot->idname = "OUTLINER_OT_collection_duplicate_linked";
642  ot->description =
643  "Recursively duplicate the collection, all its children and objects, with linked object "
644  "data";
645 
646  /* api callbacks */
649 
650  /* flags */
652 }
653 
655 {
656  /* identifiers */
657  ot->name = "Duplicate Collection";
658  ot->idname = "OUTLINER_OT_collection_duplicate";
659  ot->description =
660  "Recursively duplicate the collection, all its children, objects and object data";
661 
662  /* api callbacks */
665 
666  /* flags */
668 }
669 
672 /* -------------------------------------------------------------------- */
677 {
678  Main *bmain = CTX_data_main(C);
680  Collection *active_collection = CTX_data_layer_collection(C)->collection;
681  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
682  struct CollectionEditData data = {
683  .scene = scene,
684  .space_outliner = space_outliner,
685  };
686 
687  if ((ID_IS_LINKED(active_collection) || ID_IS_OVERRIDE_LIBRARY(active_collection)) ||
688  ((active_collection->flag & COLLECTION_IS_MASTER) &&
690  BKE_report(
691  op->reports, RPT_ERROR, "Cannot add a collection to a linked/override collection/scene");
692  return OPERATOR_CANCELLED;
693  }
694 
695  data.collections_to_edit = BLI_gset_ptr_new(__func__);
696 
697  /* We first walk over and find the Collections we actually want to link (ignoring duplicates). */
700 
701  /* Effectively link the collections. */
702  GSetIterator collections_to_edit_iter;
703  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
704  Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
705  BKE_collection_child_add(bmain, active_collection, collection);
706  id_fake_user_clear(&collection->id);
707  }
708 
709  BLI_gset_free(data.collections_to_edit, NULL);
710 
711  DEG_id_tag_update(&active_collection->id, ID_RECALC_COPY_ON_WRITE);
713 
715 
716  return OPERATOR_FINISHED;
717 }
718 
720 {
721  /* identifiers */
722  ot->name = "Link Collection";
723  ot->idname = "OUTLINER_OT_collection_link";
724  ot->description = "Link selected collections to active scene";
725 
726  /* api callbacks */
729 
730  /* flags */
732 }
733 
736 /* -------------------------------------------------------------------- */
741 {
742  Main *bmain = CTX_data_main(C);
744  ViewLayer *view_layer = CTX_data_view_layer(C);
746  struct CollectionEditData data = {
747  .scene = scene,
748  .space_outliner = space_outliner,
749  };
750 
751  data.collections_to_edit = BLI_gset_ptr_new(__func__);
752 
753  /* We first walk over and find the Collections we actually want to instance
754  * (ignoring duplicates). */
757 
758  /* Find an active collection to add to, that doesn't give dependency cycles. */
759  LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
760 
761  GSetIterator collections_to_edit_iter;
762  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
763  Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
764 
765  while (BKE_collection_cycle_find(active_lc->collection, collection)) {
766  active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
767  }
768  }
769 
770  /* Effectively instance the collections. */
771  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
772  Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
774  C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, NULL, false, 0);
775  ob->instance_collection = collection;
777  id_lib_extern(&collection->id);
778  id_us_plus(&collection->id);
779  }
780 
781  BLI_gset_free(data.collections_to_edit, NULL);
782 
784 
786 
787  return OPERATOR_FINISHED;
788 }
789 
791 {
792  /* identifiers */
793  ot->name = "Instance Collection";
794  ot->idname = "OUTLINER_OT_collection_instance";
795  ot->description = "Instance selected collections to active scene";
796 
797  /* api callbacks */
800 
801  /* flags */
803 }
804 
807 /* -------------------------------------------------------------------- */
812 {
813  struct CollectionEditData *data = customdata;
814  TreeStoreElem *tselem = TREESTORE(te);
815 
816  if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
817  return TRAVERSE_CONTINUE;
818  }
819 
820  LayerCollection *lc = te->directdata;
821 
822  if (lc->collection->flag & COLLECTION_IS_MASTER) {
823  /* skip - showing warning/error message might be misleading
824  * when deleting multiple collections, so just do nothing */
825  }
826  else {
827  /* Delete, duplicate and link don't edit children, those will come along
828  * with the parents. */
829  BLI_gset_add(data->collections_to_edit, lc);
830  }
831 
832  return TRAVERSE_CONTINUE;
833 }
834 
835 static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
836 {
837  /* Poll function so the right click menu show current state of selected collections. */
840  return false;
841  }
842 
844  struct CollectionEditData data = {
845  .scene = scene,
846  .space_outliner = space_outliner,
847  };
848  data.collections_to_edit = BLI_gset_ptr_new(__func__);
849  bool result = false;
850 
853  0,
854  TSE_SELECTED,
856  &data);
857 
858  GSetIterator collections_to_edit_iter;
859  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
860  LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
861 
862  if (clear && (lc->flag & flag)) {
863  result = true;
864  }
865  else if (!clear && !(lc->flag & flag)) {
866  result = true;
867  }
868  }
869 
870  BLI_gset_free(data.collections_to_edit, NULL);
871  return result;
872 }
873 
875 {
877 }
878 
880 {
882 }
883 
885 {
887 }
888 
890 {
892 }
893 
895 {
897 }
898 
900 {
902 }
903 
905 {
906  Main *bmain = CTX_data_main(C);
908  ViewLayer *view_layer = CTX_data_view_layer(C);
910  struct CollectionEditData data = {
911  .scene = scene,
912  .space_outliner = space_outliner,
913  };
914  bool clear = strstr(op->idname, "clear") != NULL;
915  int flag = strstr(op->idname, "holdout") ?
917  strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
919 
920  data.collections_to_edit = BLI_gset_ptr_new(__func__);
921 
924  0,
925  TSE_SELECTED,
927  &data);
928 
929  GSetIterator collections_to_edit_iter;
930  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
931  LayerCollection *lc = BLI_gsetIterator_getKey(&collections_to_edit_iter);
933  }
934 
935  BLI_gset_free(data.collections_to_edit, NULL);
936 
937  BKE_layer_collection_sync(scene, view_layer);
939 
941 
942  return OPERATOR_FINISHED;
943 }
944 
946 {
947  /* identifiers */
948  ot->name = "Disable from View Layer";
949  ot->idname = "OUTLINER_OT_collection_exclude_set";
950  ot->description = "Exclude collection from the active view layer";
951 
952  /* api callbacks */
955 
956  /* flags */
958 }
959 
961 {
962  /* identifiers */
963  ot->name = "Enable in View Layer";
964  ot->idname = "OUTLINER_OT_collection_exclude_clear";
965  ot->description = "Include collection in the active view layer";
966 
967  /* api callbacks */
970 
971  /* flags */
973 }
974 
976 {
977  /* identifiers */
978  ot->name = "Set Holdout";
979  ot->idname = "OUTLINER_OT_collection_holdout_set";
980  ot->description = "Mask collection in the active view layer";
981 
982  /* api callbacks */
985 
986  /* flags */
988 }
989 
991 {
992  /* identifiers */
993  ot->name = "Clear Holdout";
994  ot->idname = "OUTLINER_OT_collection_holdout_clear";
995  ot->description = "Clear masking of collection in the active view layer";
996 
997  /* api callbacks */
1000 
1001  /* flags */
1003 }
1004 
1006 {
1007  /* identifiers */
1008  ot->name = "Set Indirect Only";
1009  ot->idname = "OUTLINER_OT_collection_indirect_only_set";
1010  ot->description =
1011  "Set collection to only contribute indirectly (through shadows and reflections) in the view "
1012  "layer";
1013 
1014  /* api callbacks */
1017 
1018  /* flags */
1020 }
1021 
1023 {
1024  /* identifiers */
1025  ot->name = "Clear Indirect Only";
1026  ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
1027  ot->description = "Clear collection contributing only indirectly in the view layer";
1028 
1029  /* api callbacks */
1032 
1033  /* flags */
1035 }
1036 
1039 /* -------------------------------------------------------------------- */
1044 {
1046  ViewLayer *view_layer = CTX_data_view_layer(C);
1048  const bool extend = RNA_boolean_get(op->ptr, "extend");
1049  struct CollectionEditData data = {
1050  .scene = scene,
1051  .space_outliner = space_outliner,
1052  };
1053  data.collections_to_edit = BLI_gset_ptr_new(__func__);
1055  &space_outliner->tree,
1056  0,
1057  TSE_SELECTED,
1059  &data);
1060 
1061  GSetIterator collections_to_edit_iter;
1062  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1063  LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
1064 
1065  if (extend) {
1066  BKE_layer_collection_isolate_global(scene, view_layer, layer_collection, true);
1067  }
1068  else {
1069  PointerRNA ptr;
1071  RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, &ptr);
1072 
1073  /* We need to flip the value because the isolate flag routine was designed to work from the
1074  * outliner as a callback. That means the collection visibility was set before the callback
1075  * was called. */
1076  const bool value = !RNA_property_boolean_get(&ptr, prop);
1078  scene, view_layer, layer_collection, NULL, prop, "hide_viewport", value);
1079  break;
1080  }
1081  }
1082  BLI_gset_free(data.collections_to_edit, NULL);
1083 
1084  BKE_layer_collection_sync(scene, view_layer);
1086 
1088  return OPERATOR_FINISHED;
1089 }
1090 
1091 static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1092 {
1093  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
1094  if (!RNA_property_is_set(op->ptr, prop) && (event->shift)) {
1095  RNA_property_boolean_set(op->ptr, prop, true);
1096  }
1097  return collection_isolate_exec(C, op);
1098 }
1099 
1101 {
1102  /* identifiers */
1103  ot->name = "Isolate Collection";
1104  ot->idname = "OUTLINER_OT_collection_isolate";
1105  ot->description = "Hide all but this collection and its parents";
1106 
1107  /* api callbacks */
1111 
1112  /* flags */
1114 
1115  /* properties */
1116  PropertyRNA *prop = RNA_def_boolean(
1117  ot->srna, "extend", false, "Extend", "Extend current visible collections");
1119 }
1120 
1122 {
1124 }
1125 
1127 {
1129 }
1130 
1132 {
1134  return false;
1135  }
1137 }
1138 
1140 {
1142  ViewLayer *view_layer = CTX_data_view_layer(C);
1144  const bool is_inside = strstr(op->idname, "inside") != NULL;
1145  const bool show = strstr(op->idname, "show") != NULL;
1146  struct CollectionEditData data = {
1147  .scene = scene,
1148  .space_outliner = space_outliner,
1149  };
1150  data.collections_to_edit = BLI_gset_ptr_new(__func__);
1151 
1153  &space_outliner->tree,
1154  0,
1155  TSE_SELECTED,
1157  &data);
1158 
1159  GSetIterator collections_to_edit_iter;
1160  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1161  LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
1162  BKE_layer_collection_set_visible(view_layer, layer_collection, show, is_inside);
1163  }
1164  BLI_gset_free(data.collections_to_edit, NULL);
1165 
1166  BKE_layer_collection_sync(scene, view_layer);
1168 
1170  return OPERATOR_FINISHED;
1171 }
1172 
1174 {
1175  /* identifiers */
1176  ot->name = "Show Collection";
1177  ot->idname = "OUTLINER_OT_collection_show";
1178  ot->description = "Show the collection in this view layer";
1179 
1180  /* api callbacks */
1183 
1184  /* flags */
1186 }
1187 
1189 {
1190  /* identifiers */
1191  ot->name = "Hide Collection";
1192  ot->idname = "OUTLINER_OT_collection_hide";
1193  ot->description = "Hide the collection in this view layer";
1194 
1195  /* api callbacks */
1198 
1199  /* flags */
1201 }
1202 
1204 {
1205  /* identifiers */
1206  ot->name = "Show Inside Collection";
1207  ot->idname = "OUTLINER_OT_collection_show_inside";
1208  ot->description = "Show all the objects and collections inside the collection";
1209 
1210  /* api callbacks */
1213 
1214  /* flags */
1216 }
1217 
1219 {
1220  /* identifiers */
1221  ot->name = "Hide Inside Collection";
1222  ot->idname = "OUTLINER_OT_collection_hide_inside";
1223  ot->description = "Hide all the objects and collections inside the collection";
1224 
1225  /* api callbacks */
1228 
1229  /* flags */
1231 }
1232 
1235 /* -------------------------------------------------------------------- */
1239 static bool collection_flag_poll(bContext *C, bool clear, int flag)
1240 {
1242  return false;
1243  }
1244 
1246  if (te == NULL) {
1247  return false;
1248  }
1249 
1251  if (collection == NULL) {
1252  return false;
1253  }
1254 
1255  if (clear && (collection->flag & flag)) {
1256  return true;
1257  }
1258  if (!clear && !(collection->flag & flag)) {
1259  return true;
1260  }
1261 
1262  return false;
1263 }
1264 
1266 {
1268 }
1269 
1271 {
1273 }
1274 
1276 {
1278 }
1279 
1281 {
1283 }
1284 
1286 {
1288  ViewLayer *view_layer = CTX_data_view_layer(C);
1290  const bool is_render = strstr(op->idname, "render");
1291  const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
1293  struct CollectionEditData data = {
1294  .scene = scene,
1295  .space_outliner = space_outliner,
1296  };
1297  data.collections_to_edit = BLI_gset_ptr_new(__func__);
1298  const bool has_layer_collection = space_outliner->outlinevis == SO_VIEW_LAYER;
1299 
1300  if (has_layer_collection) {
1302  &space_outliner->tree,
1303  0,
1304  TSE_SELECTED,
1306  &data);
1307  GSetIterator collections_to_edit_iter;
1308  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1309  LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
1310  Collection *collection = layer_collection->collection;
1311  if (ID_IS_LINKED(collection)) {
1312  continue;
1313  }
1314  if (clear) {
1315  collection->flag &= ~flag;
1316  }
1317  else {
1318  collection->flag |= flag;
1319  }
1320 
1321  /* Make sure (at least for this view layer) the collection is visible. */
1322  if (clear && !is_render) {
1323  layer_collection->flag &= ~LAYER_COLLECTION_HIDE;
1324  }
1325  }
1326  BLI_gset_free(data.collections_to_edit, NULL);
1327  }
1328  else {
1330  &space_outliner->tree,
1331  0,
1332  TSE_SELECTED,
1334  &data);
1335  GSetIterator collections_to_edit_iter;
1336  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1337  Collection *collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
1338  if (ID_IS_LINKED(collection)) {
1339  continue;
1340  }
1341 
1342  if (clear) {
1343  collection->flag &= ~flag;
1344  }
1345  else {
1346  collection->flag |= flag;
1347  }
1348  }
1349  BLI_gset_free(data.collections_to_edit, NULL);
1350  }
1351 
1352  BKE_layer_collection_sync(scene, view_layer);
1354 
1355  if (!is_render) {
1357  }
1358 
1360  return OPERATOR_FINISHED;
1361 }
1362 
1364 {
1365  /* identifiers */
1366  ot->name = "Enable Collection";
1367  ot->idname = "OUTLINER_OT_collection_enable";
1368  ot->description = "Enable viewport display in the view layers";
1369 
1370  /* api callbacks */
1373 
1374  /* flags */
1376 }
1377 
1379 {
1380  /* identifiers */
1381  ot->name = "Disable Collection";
1382  ot->idname = "OUTLINER_OT_collection_disable";
1383  ot->description = "Disable viewport display in the view layers";
1384 
1385  /* api callbacks */
1388 
1389  /* flags */
1391 }
1392 
1394 {
1395  /* identifiers */
1396  ot->name = "Enable Collection in Render";
1397  ot->idname = "OUTLINER_OT_collection_enable_render";
1398  ot->description = "Render the collection";
1399 
1400  /* api callbacks */
1403 
1404  /* flags */
1406 }
1407 
1409 {
1410  /* identifiers */
1411  ot->name = "Disable Collection in Render";
1412  ot->idname = "OUTLINER_OT_collection_disable_render";
1413  ot->description = "Do not render this collection";
1414 
1415  /* api callbacks */
1418 
1419  /* flags */
1421 }
1422 
1429 };
1430 
1433 /* -------------------------------------------------------------------- */
1438 {
1439  struct OutlinerHideEditData *data = customdata;
1440  TreeStoreElem *tselem = TREESTORE(te);
1441 
1442  if (tselem == NULL) {
1443  return TRAVERSE_CONTINUE;
1444  }
1445 
1446  if (tselem->type == TSE_LAYER_COLLECTION) {
1447  LayerCollection *lc = te->directdata;
1448 
1449  if (lc->collection->flag & COLLECTION_IS_MASTER) {
1450  /* Skip - showing warning/error message might be misleading
1451  * when deleting multiple collections, so just do nothing. */
1452  }
1453  else {
1454  /* Delete, duplicate and link don't edit children,
1455  * those will come along with the parents. */
1456  BLI_gset_add(data->collections_to_edit, lc);
1457  }
1458  }
1459  else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1460  Object *ob = (Object *)tselem->id;
1461  Base *base = BKE_view_layer_base_find(data->view_layer, ob);
1462  BLI_gset_add(data->bases_to_edit, base);
1463  }
1464 
1465  return TRAVERSE_CONTINUE;
1466 }
1467 
1469 {
1473  struct OutlinerHideEditData data = {
1474  .scene = scene,
1475  .view_layer = view_layer,
1476  .space_outliner = space_outliner,
1477  };
1478  data.collections_to_edit = BLI_gset_ptr_new("outliner_hide_exec__collections_to_edit");
1479  data.bases_to_edit = BLI_gset_ptr_new("outliner_hide_exec__bases_to_edit");
1480 
1482  &space_outliner->tree,
1483  0,
1484  TSE_SELECTED,
1486  &data);
1487 
1488  GSetIterator collections_to_edit_iter;
1489  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1490  LayerCollection *layer_collection = BLI_gsetIterator_getKey(&collections_to_edit_iter);
1491  BKE_layer_collection_set_visible(view_layer, layer_collection, false, false);
1492  }
1493  BLI_gset_free(data.collections_to_edit, NULL);
1494 
1495  GSetIterator bases_to_edit_iter;
1496  GSET_ITER (bases_to_edit_iter, data.bases_to_edit) {
1497  Base *base = BLI_gsetIterator_getKey(&bases_to_edit_iter);
1498  base->flag |= BASE_HIDDEN;
1499  }
1500  BLI_gset_free(data.bases_to_edit, NULL);
1501 
1504 
1506  return OPERATOR_FINISHED;
1507 }
1508 
1510 {
1511  /* identifiers */
1512  ot->name = "Hide";
1513  ot->idname = "OUTLINER_OT_hide";
1514  ot->description = "Hide selected objects and collections";
1515 
1516  /* api callbacks */
1519 
1520  /* flags */
1522 }
1523 
1525 {
1528 
1529  /* Unhide all the collections. */
1531  LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1533  }
1534 
1535  /* Unhide all objects. */
1537  base->flag &= ~BASE_HIDDEN;
1538  }
1539 
1542 
1544  return OPERATOR_FINISHED;
1545 }
1546 
1548 {
1549  /* identifiers */
1550  ot->name = "Unhide All";
1551  ot->idname = "OUTLINER_OT_unhide_all";
1552  ot->description = "Unhide all objects and collections";
1553 
1554  /* api callbacks */
1557 
1558  /* flags */
1560 }
1561 
1564 /* -------------------------------------------------------------------- */
1569 {
1572  const short color_tag = RNA_enum_get(op->ptr, "color");
1573 
1574  struct IDsSelectedData selected = {
1575  .selected_array = {NULL, NULL},
1576  };
1577 
1578  outliner_tree_traverse(space_outliner,
1579  &space_outliner->tree,
1580  0,
1581  TSE_SELECTED,
1583  &selected);
1584 
1585  LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
1586  TreeElement *te_selected = (TreeElement *)link->data;
1587 
1588  Collection *collection = outliner_collection_from_tree_element(te_selected);
1589  if (collection == scene->master_collection) {
1590  continue;
1591  }
1592  if (ID_IS_LINKED(collection)) {
1593  BKE_report(op->reports, RPT_WARNING, "Can't add a color tag to a linked collection");
1594  continue;
1595  }
1596 
1597  collection->color_tag = color_tag;
1598  };
1599 
1600  BLI_freelistN(&selected.selected_array);
1601 
1603 
1604  return OPERATOR_FINISHED;
1605 }
1606 
1608 {
1609  /* identifiers */
1610  ot->name = "Set Color Tag";
1611  ot->idname = "OUTLINER_OT_collection_color_tag_set";
1612  ot->description = "Set a color tag for the selected collections";
1613 
1614  /* api callbacks */
1617 
1618  /* flags */
1620 
1621  RNA_def_enum(
1622  ot->srna, "color", rna_enum_collection_color_items, COLLECTION_COLOR_NONE, "Color Tag", "");
1623 }
1624 
struct Collection * BKE_collection_add(struct Main *bmain, struct Collection *parent, const char *name)
Definition: collection.c:435
bool BKE_collection_cycle_find(struct Collection *new_ancestor, struct Collection *collection)
Definition: collection.c:1450
bool BKE_collection_child_add(struct Main *bmain, struct Collection *parent, struct Collection *child)
Definition: collection.c:1606
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy)
Definition: collection.c:520
struct Collection * BKE_collection_duplicate(struct Main *bmain, struct Collection *parent, struct Collection *collection, const uint duplicate_flags, const uint duplicate_options)
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
Definition: context.c:836
struct LayerCollection * CTX_data_layer_collection(const bContext *C)
Definition: context.c:1077
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1044
struct wmMsgBus * CTX_wm_message_bus(const bContext *C)
Definition: context.c:746
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
void BKE_layer_collection_set_flag(struct LayerCollection *lc, const int flag, const bool value)
Definition: layer.c:1477
bool BKE_layer_collection_objects_select(struct ViewLayer *view_layer, struct LayerCollection *lc, bool deselect)
Definition: layer.c:1031
struct LayerCollection * BKE_layer_collection_get_active(struct ViewLayer *view_layer)
Definition: layer.c:630
void BKE_layer_collection_isolate_global(struct Scene *scene, struct ViewLayer *view_layer, struct LayerCollection *lc, bool extend)
Definition: layer.c:1206
struct LayerCollection * BKE_layer_collection_activate_parent(struct ViewLayer *view_layer, struct LayerCollection *lc)
Definition: layer.c:651
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
Definition: layer.c:394
void BKE_layer_collection_sync(const struct Scene *scene, struct ViewLayer *view_layer)
void BKE_layer_collection_set_visible(struct ViewLayer *view_layer, struct LayerCollection *lc, const bool visible, const bool hierarchy)
Definition: layer.c:1414
void id_lib_extern(struct ID *id)
Definition: lib_id.c:207
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
void id_fake_user_clear(struct ID *id)
Definition: lib_id.c:336
@ LIB_ID_DUPLICATE_IS_ROOT_ID
Definition: BKE_lib_id.h:178
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct GSet GSet
Definition: BLI_ghash.h:189
GSet * BLI_gset_ptr_new(const char *info)
#define GSET_ITER(gs_iter_, gset_)
Definition: BLI_ghash.h:268
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1253
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:255
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:1160
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:923
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
@ ID_RECALC_SELECT
Definition: DNA_ID.h:638
@ ID_RECALC_BASE_FLAGS
Definition: DNA_ID.h:641
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:524
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:482
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
@ ID_SCE
Definition: DNA_ID_enums.h:57
@ ID_GR
Definition: DNA_ID_enums.h:77
@ ID_OB
Definition: DNA_ID_enums.h:59
Object groups, one object can be in many groups at once.
@ COLLECTION_COLOR_NONE
@ COLLECTION_RESTRICT_RENDER
@ COLLECTION_RESTRICT_VIEWPORT
@ COLLECTION_IS_MASTER
@ 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_DUPLICOLLECTION
@ OB_EMPTY
@ TSE_VIEW_COLLECTION_BASE
@ TSE_SCENE_COLLECTION_BASE
@ TSE_LAYER_COLLECTION
@ TSE_SOME_ID
@ TSE_R_LAYER
@ TSE_SELECTED
#define BASACT(_view_layer)
@ SO_LIBRARIES
@ SO_VIEW_LAYER
@ SO_SCENES
eDupli_ID_Flags
@ USER_DUP_OBJECT
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
struct Object * ED_object_add_type(struct bContext *C, const int type, const char *name, const float loc[3], const float rot[3], const bool enter_editmode, const unsigned short local_view_bits) ATTR_NONNULL(1) ATTR_RETURNS_NONNULL
Definition: object_add.c:659
void ED_outliner_select_sync_from_object_tag(struct bContext *C)
Definition: outliner_sync.c:56
StructRNA RNA_LayerCollection
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_OB_SELECT
Definition: WM_types.h:342
#define NC_SCENE
Definition: WM_types.h:279
#define ND_LAYER_CONTENT
Definition: WM_types.h:354
#define ND_LAYER
Definition: WM_types.h:350
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
static bool is_inside(int x, int y, int cols, int rows)
Definition: filesel.c:663
#define GS(x)
Definition: iris.c:241
static void clear(Message *msg)
Definition: msgfmt.c:294
bool active
all scheduled work for the GPU.
static bool outliner_view_layer_collections_editor_poll(bContext *C)
static bool collections_indirect_only_clear_poll(bContext *C)
void OUTLINER_OT_collection_disable(wmOperatorType *ot)
static int collection_new_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_show_inside(wmOperatorType *ot)
void OUTLINER_OT_collection_objects_deselect(wmOperatorType *ot)
static int collection_isolate_exec(bContext *C, wmOperator *op)
static bool collections_exclude_set_poll(bContext *C)
void OUTLINER_OT_collection_duplicate_linked(wmOperatorType *ot)
static bool collections_holdout_clear_poll(bContext *C)
Collection * outliner_collection_from_tree_element(const TreeElement *te)
static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void *customdata)
void OUTLINER_OT_unhide_all(wmOperatorType *ot)
void OUTLINER_OT_collection_instance(wmOperatorType *ot)
static bool collections_indirect_only_set_poll(bContext *C)
static bool collection_hide_poll(bContext *C)
static bool collection_enable_poll(bContext *C)
static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
void OUTLINER_OT_collection_holdout_set(wmOperatorType *ot)
void outliner_collection_delete(bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool hierarchy)
static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te, void *customdata)
void OUTLINER_OT_collection_exclude_set(wmOperatorType *ot)
static int collection_visibility_exec(bContext *C, wmOperator *op)
void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
static int collection_flag_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_objects_select(wmOperatorType *ot)
static bool collections_exclude_clear_poll(bContext *C)
TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *customdata)
void OUTLINER_OT_collection_new(wmOperatorType *ot)
bool ED_outliner_collections_editor_poll(bContext *C)
static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata)
void OUTLINER_OT_collection_duplicate(wmOperatorType *ot)
TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata)
void OUTLINER_OT_collection_hide_inside(wmOperatorType *ot)
static bool collection_show_poll(bContext *C)
void OUTLINER_OT_collection_holdout_clear(wmOperatorType *ot)
void OUTLINER_OT_collection_indirect_only_clear(wmOperatorType *ot)
void OUTLINER_OT_collection_disable_render(wmOperatorType *ot)
static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, void *customdata)
void OUTLINER_OT_collection_hide(wmOperatorType *ot)
static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *customdata)
static bool collection_disable_poll(bContext *C)
static TreeElement * outliner_active_collection(bContext *C)
static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op))
void OUTLINER_OT_collection_exclude_clear(wmOperatorType *ot)
static int collection_objects_select_exec(bContext *C, wmOperator *op)
static int collection_hierarchy_delete_exec(bContext *C, wmOperator *op)
static bool collections_holdout_set_poll(bContext *C)
static int collection_link_exec(bContext *C, wmOperator *op)
bool outliner_is_collection_tree_element(const TreeElement *te)
static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
void OUTLINER_OT_collection_enable_render(wmOperatorType *ot)
static bool collection_enable_render_poll(bContext *C)
static LayerCollection * outliner_active_layer_collection(bContext *C)
void OUTLINER_OT_collection_enable(wmOperatorType *ot)
static int outliner_unhide_all_exec(bContext *C, wmOperator *UNUSED(op))
void OUTLINER_OT_collection_indirect_only_set(wmOperatorType *ot)
static TreeTraversalAction outliner_hide_find_data_to_edit(TreeElement *te, void *customdata)
static bool collection_edit_in_active_scene_poll(bContext *C)
void OUTLINER_OT_hide(wmOperatorType *ot)
static int collection_duplicate_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_color_tag_set(wmOperatorType *ot)
static bool collection_inside_poll(bContext *C)
static bool collection_disable_render_poll(bContext *C)
void OUTLINER_OT_collection_hierarchy_delete(wmOperatorType *ot)
static int collection_view_layer_exec(bContext *C, wmOperator *op)
static bool collection_flag_poll(bContext *C, bool clear, int flag)
void OUTLINER_OT_collection_isolate(wmOperatorType *ot)
void OUTLINER_OT_collection_show(wmOperatorType *ot)
static int outliner_color_tag_set_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_link(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)
bool outliner_tree_traverse(const SpaceOutliner *space_outliner, ListBase *tree, int filter_te_flag, int filter_tselem_flag, TreeTraversalFunc func, void *customdata)
void outliner_build_tree(struct Main *mainvar, struct Scene *scene, struct ViewLayer *view_layer, struct SpaceOutliner *space_outliner, struct ARegion *region)
#define TREESTORE(a)
void outliner_cleanup_tree(struct SpaceOutliner *space_outliner)
TreeTraversalAction
@ TRAVERSE_SKIP_CHILDS
@ TRAVERSE_BREAK
@ TRAVERSE_CONTINUE
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2331
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
Definition: rna_access.c:953
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2358
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
const EnumPropertyItem rna_enum_collection_color_items[]
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
short flag
SpaceOutliner * space_outliner
IDTypeEmbeddedOwnerGetFunction owner_get
Definition: BKE_idtype.h:189
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
short flag
Definition: DNA_ID.h:288
char name[66]
Definition: DNA_ID.h:283
struct ListBase selected_array
ListBase layer_collections
struct Collection * collection
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase collections
Definition: BKE_main.h:167
short transflag
struct Collection * instance_collection
SpaceOutliner * space_outliner
struct Collection * master_collection
View3DCursor cursor
struct TreeElement * parent
void * directdata
ListBase layer_collections
ListBase object_bases
short shift
Definition: WM_types.h:618
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct PointerRNA * ptr
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)