Blender  V3.3
outliner_collections.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <cstring>
8 
9 #include "BLI_listbase.h"
10 #include "BLI_utildefines.h"
11 
12 #include "DNA_ID.h"
13 #include "DNA_collection_types.h"
14 #include "DNA_object_types.h"
15 
16 #include "BKE_collection.h"
17 #include "BKE_context.h"
18 #include "BKE_idtype.h"
19 #include "BKE_layer.h"
20 #include "BKE_lib_id.h"
21 #include "BKE_main.h"
22 #include "BKE_report.h"
23 
24 #include "DEG_depsgraph.h"
25 #include "DEG_depsgraph_build.h"
26 
27 #include "ED_object.h"
28 #include "ED_outliner.h"
29 #include "ED_screen.h"
30 
31 #include "WM_api.h"
32 #include "WM_message.h"
33 #include "WM_types.h"
34 
35 #include "RNA_access.h"
36 #include "RNA_define.h"
37 #include "RNA_enum_types.h"
38 
39 #include "outliner_intern.hh" /* own include */
40 
41 /* -------------------------------------------------------------------- */
46 {
47  TreeStoreElem *tselem = TREESTORE(te);
48 
49  if (!tselem) {
50  return false;
51  }
52 
53  if (ELEM(tselem->type,
57  return true;
58  }
59  if ((tselem->type == TSE_SOME_ID) && te->idcode == ID_GR) {
60  return true;
61  }
62 
63  return false;
64 }
65 
67 {
68  TreeStoreElem *tselem = TREESTORE(te);
69 
70  if (!tselem) {
71  return nullptr;
72  }
73 
74  if (tselem->type == TSE_LAYER_COLLECTION) {
75  LayerCollection *lc = reinterpret_cast<LayerCollection *>(te->directdata);
76  return lc->collection;
77  }
79  Scene *scene = (Scene *)tselem->id;
80  return scene->master_collection;
81  }
82  if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_GR)) {
83  return (Collection *)tselem->id;
84  }
85 
86  return nullptr;
87 }
88 
90 {
91  struct IDsSelectedData *data = reinterpret_cast<IDsSelectedData *>(customdata);
92  TreeStoreElem *tselem = TREESTORE(te);
93 
95  BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
96  return TRAVERSE_CONTINUE;
97  }
98 
99  if ((tselem->type != TSE_SOME_ID) || (tselem->id && GS(tselem->id->name) != ID_GR)) {
100  return TRAVERSE_SKIP_CHILDS;
101  }
102 
103  return TRAVERSE_CONTINUE;
104 }
105 
107 {
108  struct IDsSelectedData *data = reinterpret_cast<IDsSelectedData *>(customdata);
109  TreeStoreElem *tselem = TREESTORE(te);
110 
112  return TRAVERSE_CONTINUE;
113  }
114 
115  if ((tselem->type != TSE_SOME_ID) || (tselem->id == nullptr) ||
116  (GS(tselem->id->name) != ID_OB)) {
117  return TRAVERSE_SKIP_CHILDS;
118  }
119 
120  BLI_addtail(&data->selected_array, BLI_genericNodeN(te));
121 
122  return TRAVERSE_CONTINUE;
123 }
124 
126 {
127  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
128  struct IDsSelectedData data = {{nullptr}};
129  outliner_tree_traverse(space_outliner,
130  &space_outliner->tree,
131  0,
132  TSE_SELECTED,
134  &data);
135  LISTBASE_FOREACH (LinkData *, link, &data.selected_array) {
136  TreeElement *ten_selected = (TreeElement *)link->data;
137  Object *ob = (Object *)TREESTORE(ten_selected)->id;
138  BLI_addtail(objects, BLI_genericNodeN(ob));
139  }
140  BLI_freelistN(&data.selected_array);
141 }
142 
145 /* -------------------------------------------------------------------- */
150 {
151  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
152  return (space_outliner != nullptr) &&
153  ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES, SO_LIBRARIES);
154 }
155 
157 {
158  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
159  return (space_outliner != nullptr) && (space_outliner->outlinevis == SO_VIEW_LAYER);
160 }
161 
163 {
165  return false;
166  }
169  return false;
170  }
171  return true;
172 }
173 
176 /* -------------------------------------------------------------------- */
181  bool error;
183 };
184 
186 {
187  struct CollectionNewData *data = reinterpret_cast<CollectionNewData *>(customdata);
189 
190  if (!collection) {
191  return TRAVERSE_SKIP_CHILDS;
192  }
193 
194  if (data->collection != nullptr) {
195  data->error = true;
196  return TRAVERSE_BREAK;
197  }
198 
199  data->collection = collection;
200  return TRAVERSE_CONTINUE;
201 }
202 
204 {
205  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
206  ARegion *region = CTX_wm_region(C);
207  Main *bmain = CTX_data_main(C);
209  ViewLayer *view_layer = CTX_data_view_layer(C);
210 
212 
213  if (RNA_boolean_get(op->ptr, "nested")) {
214  outliner_build_tree(bmain, scene, view_layer, space_outliner, region);
215 
216  outliner_tree_traverse(space_outliner,
217  &space_outliner->tree,
218  0,
219  TSE_SELECTED,
221  &data);
222 
223  if (data.error) {
224  BKE_report(op->reports, RPT_ERROR, "More than one collection is selected");
225  return OPERATOR_CANCELLED;
226  }
227  }
228 
229  if (data.collection == nullptr || ID_IS_LINKED(data.collection) ||
230  ID_IS_OVERRIDE_LIBRARY(data.collection)) {
231  data.collection = scene->master_collection;
232  }
233 
235  BKE_report(op->reports, RPT_ERROR, "Can't add a new collection to linked/override scene");
236  return OPERATOR_CANCELLED;
237  }
238 
239  BKE_collection_add(bmain, data.collection, nullptr);
240 
243 
244  outliner_cleanup_tree(space_outliner);
246  return OPERATOR_FINISHED;
247 }
248 
250 {
251  /* identifiers */
252  ot->name = "New Collection";
253  ot->idname = "OUTLINER_OT_collection_new";
254  ot->description = "Add a new collection inside selected collection";
255 
256  /* api callbacks */
259 
260  /* flags */
262 
263  /* properties */
265  ot->srna, "nested", true, "Nested", "Add as child of selected collection");
267 }
268 
271 /* -------------------------------------------------------------------- */
279 
280  /* Whether the processed operation should be allowed on liboverride collections, or not. */
282  /* Whether the processed operation should be allowed on hierarchy roots of liboverride
283  * collections, or not. */
285 };
286 
288 {
289  CollectionEditData *data = reinterpret_cast<CollectionEditData *>(customdata);
291 
292  if (!collection) {
293  return TRAVERSE_SKIP_CHILDS;
294  }
295 
296  if (collection->flag & COLLECTION_IS_MASTER) {
297  /* Skip - showing warning/error message might be misleading
298  * when deleting multiple collections, so just do nothing. */
299  return TRAVERSE_CONTINUE;
300  }
301 
302  if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
303  if (ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(collection)) {
304  if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) {
305  return TRAVERSE_SKIP_CHILDS;
306  }
307  }
308  else {
309  if (!data->is_liboverride_allowed) {
310  return TRAVERSE_SKIP_CHILDS;
311  }
312  }
313  }
314 
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 
322  bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
323 {
324  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
325 
327  data.scene = scene;
328  data.space_outliner = space_outliner;
329  data.is_liboverride_allowed = false;
330  data.is_liboverride_hierarchy_root_allowed = do_hierarchy;
331 
332  data.collections_to_edit = BLI_gset_ptr_new(__func__);
333 
334  /* We first walk over and find the Collections we actually want to delete
335  * (ignoring duplicates). */
337  space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
338 
339  /* Effectively delete the collections. */
340  GSetIterator collections_to_edit_iter;
341  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
342  Collection *collection = reinterpret_cast<Collection *>(
343  BLI_gsetIterator_getKey(&collections_to_edit_iter));
344 
345  /* Test in case collection got deleted as part of another one. */
346  if (BLI_findindex(&bmain->collections, collection) != -1) {
347  /* We cannot allow deleting collections that are indirectly linked,
348  * or that are used by (linked to...) other linked scene/collection. */
349  bool skip = false;
350  if (ID_IS_LINKED(collection)) {
351  if (collection->id.tag & LIB_TAG_INDIRECT) {
352  skip = true;
353  }
354  else {
355  LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
356  Collection *parent = cparent->collection;
357  if (ID_IS_LINKED(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) {
358  skip = true;
359  break;
360  }
361  if (parent->flag & COLLECTION_IS_MASTER) {
362  BLI_assert(parent->id.flag & LIB_EMBEDDED_DATA);
363 
364  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(&parent->id);
365  BLI_assert(id_type->owner_get != nullptr);
366 
367  ID *scene_owner = id_type->owner_get(bmain, &parent->id, NULL);
368  BLI_assert(GS(scene_owner->name) == ID_SCE);
369  if (ID_IS_LINKED(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
370  skip = true;
371  break;
372  }
373  }
374  }
375  }
376  }
377 
378  if (!skip) {
379  BKE_collection_delete(bmain, collection, do_hierarchy);
380  }
381  else {
382  BKE_reportf(reports,
383  RPT_WARNING,
384  "Cannot delete collection '%s', it is either a linked one used by other "
385  "linked scenes/collections, or a library override one",
386  collection->id.name + 2);
387  }
388  }
389  }
390 
391  BLI_gset_free(data.collections_to_edit, nullptr);
392 }
393 
395 {
396  Main *bmain = CTX_data_main(C);
398  ViewLayer *view_layer = CTX_data_view_layer(C);
399  struct wmMsgBus *mbus = CTX_wm_message_bus(C);
400  const Base *basact_prev = BASACT(view_layer);
401 
402  outliner_collection_delete(C, bmain, scene, op->reports, true);
403 
406 
408 
409  if (basact_prev != BASACT(view_layer)) {
410  WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active);
411  }
412 
414 
415  return OPERATOR_FINISHED;
416 }
417 
419 {
420  /* identifiers */
421  ot->name = "Delete Hierarchy";
422  ot->idname = "OUTLINER_OT_collection_hierarchy_delete";
423  ot->description = "Delete selected collection hierarchies";
424 
425  /* api callbacks */
428 
429  /* flags */
431 }
432 
435 /* -------------------------------------------------------------------- */
440  bool error;
442 };
443 
445  void *customdata)
446 {
447  CollectionObjectsSelectData *data = reinterpret_cast<CollectionObjectsSelectData *>(customdata);
448  TreeStoreElem *tselem = TREESTORE(te);
449 
450  switch (tselem->type) {
452  data->layer_collection = reinterpret_cast<LayerCollection *>(te->directdata);
453  return TRAVERSE_BREAK;
454  case TSE_R_LAYER:
457  return TRAVERSE_CONTINUE;
458  default:
459  return TRAVERSE_SKIP_CHILDS;
460  }
461 }
462 
464 {
465  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
466 
468 
469  outliner_tree_traverse(space_outliner,
470  &space_outliner->tree,
471  0,
472  TSE_SELECTED,
474  &data);
475  return data.layer_collection;
476 }
477 
479 {
480  ViewLayer *view_layer = CTX_data_view_layer(C);
482  bool deselect = STREQ(op->idname, "OUTLINER_OT_collection_objects_deselect");
483 
484  if (layer_collection == nullptr) {
485  return OPERATOR_CANCELLED;
486  }
487 
488  BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
489 
494 
495  return OPERATOR_FINISHED;
496 }
497 
499 {
500  /* identifiers */
501  ot->name = "Select Objects";
502  ot->idname = "OUTLINER_OT_collection_objects_select";
503  ot->description = "Select objects in collection";
504 
505  /* api callbacks */
508 
509  /* flags */
511 }
512 
514 {
515  /* identifiers */
516  ot->name = "Deselect Objects";
517  ot->idname = "OUTLINER_OT_collection_objects_deselect";
518  ot->description = "Deselect objects in collection";
519 
520  /* api callbacks */
523 
524  /* flags */
526 }
527 
530 /* -------------------------------------------------------------------- */
536 };
537 
539  void *customdata)
540 {
541  CollectionDuplicateData *data = reinterpret_cast<CollectionDuplicateData *>(customdata);
542  TreeStoreElem *tselem = TREESTORE(te);
543 
544  switch (tselem->type) {
546  data->te = te;
547  return TRAVERSE_BREAK;
548  case TSE_R_LAYER:
551  default:
552  return TRAVERSE_CONTINUE;
553  }
554 }
555 
557 {
558  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
559 
561 
562  outliner_tree_traverse(space_outliner,
563  &space_outliner->tree,
564  0,
565  TSE_SELECTED,
567  &data);
568  return data.te;
569 }
570 
572 {
573  Main *bmain = CTX_data_main(C);
575  const bool linked = strstr(op->idname, "linked") != nullptr;
576 
577  /* Can happen when calling from a key binding. */
578  if (te == nullptr) {
579  BKE_report(op->reports, RPT_ERROR, "No active collection");
580  return OPERATOR_CANCELLED;
581  }
582 
584  Collection *parent = (te->parent) ? outliner_collection_from_tree_element(te->parent) : nullptr;
585 
586  /* We are allowed to duplicated linked collections (they will become local IDs then),
587  * but we should not allow its parent to be a linked ID, ever.
588  * This can happen when a whole scene is linked e.g. */
589  if (parent != nullptr && (ID_IS_LINKED(parent) || ID_IS_OVERRIDE_LIBRARY(parent))) {
591  parent = (ID_IS_LINKED(scene) || ID_IS_OVERRIDE_LIBRARY(scene)) ? nullptr :
593  }
594  else if (parent != nullptr && (parent->flag & COLLECTION_IS_MASTER) != 0) {
595  BLI_assert(parent->id.flag & LIB_EMBEDDED_DATA);
596 
597  const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(&parent->id);
598  BLI_assert(id_type->owner_get != nullptr);
599 
600  Scene *scene_owner = (Scene *)id_type->owner_get(bmain, &parent->id, NULL);
601  BLI_assert(scene_owner != nullptr);
602  BLI_assert(GS(scene_owner->id.name) == ID_SCE);
603 
604  if (ID_IS_LINKED(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) {
605  scene_owner = CTX_data_scene(C);
606  parent = (ID_IS_LINKED(scene_owner) || ID_IS_OVERRIDE_LIBRARY(scene_owner)) ?
607  nullptr :
608  scene_owner->master_collection;
609  }
610  }
611 
612  if (collection->flag & COLLECTION_IS_MASTER) {
613  BKE_report(op->reports, RPT_ERROR, "Can't duplicate the master collection");
614  return OPERATOR_CANCELLED;
615  }
616 
617  if (parent == nullptr) {
618  BKE_report(op->reports,
619  RPT_WARNING,
620  "Could not find a valid parent collection for the new duplicate, "
621  "it won't be linked to any view layer");
622  }
623 
624  const eDupli_ID_Flags dupli_flags = (eDupli_ID_Flags)(USER_DUP_OBJECT |
625  (linked ? 0 : U.dupflag));
626  BKE_collection_duplicate(bmain, parent, collection, dupli_flags, LIB_ID_DUPLICATE_IS_ROOT_ID);
627 
631 
632  return OPERATOR_FINISHED;
633 }
634 
636 {
637  /* identifiers */
638  ot->name = "Duplicate Linked Collection";
639  ot->idname = "OUTLINER_OT_collection_duplicate_linked";
640  ot->description =
641  "Recursively duplicate the collection, all its children and objects, with linked object "
642  "data";
643 
644  /* api callbacks */
647 
648  /* flags */
650 }
651 
653 {
654  /* identifiers */
655  ot->name = "Duplicate Collection";
656  ot->idname = "OUTLINER_OT_collection_duplicate";
657  ot->description =
658  "Recursively duplicate the collection, all its children, objects and object data";
659 
660  /* api callbacks */
663 
664  /* flags */
666 }
667 
670 /* -------------------------------------------------------------------- */
675 {
676  Main *bmain = CTX_data_main(C);
678  Collection *active_collection = CTX_data_layer_collection(C)->collection;
679  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
680 
682  data.scene = scene;
683  data.space_outliner = space_outliner;
684  data.is_liboverride_allowed = false; /* No linking of non-root collections. */
685  data.is_liboverride_hierarchy_root_allowed = true;
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). */
699  space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
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 = reinterpret_cast<Collection *>(
705  BLI_gsetIterator_getKey(&collections_to_edit_iter));
706  BKE_collection_child_add(bmain, active_collection, collection);
707  id_fake_user_clear(&collection->id);
708  }
709 
710  BLI_gset_free(data.collections_to_edit, nullptr);
711 
712  DEG_id_tag_update(&active_collection->id, ID_RECALC_COPY_ON_WRITE);
714 
716 
717  return OPERATOR_FINISHED;
718 }
719 
721 {
722  /* identifiers */
723  ot->name = "Link Collection";
724  ot->idname = "OUTLINER_OT_collection_link";
725  ot->description = "Link selected collections to active scene";
726 
727  /* api callbacks */
730 
731  /* flags */
733 }
734 
737 /* -------------------------------------------------------------------- */
742 {
743  Main *bmain = CTX_data_main(C);
745  ViewLayer *view_layer = CTX_data_view_layer(C);
746  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
748  data.scene = scene;
749  data.space_outliner = space_outliner;
750  data.is_liboverride_allowed = false; /* No instancing of non-root collections. */
751  data.is_liboverride_hierarchy_root_allowed = true;
752 
753  data.collections_to_edit = BLI_gset_ptr_new(__func__);
754 
755  /* We first walk over and find the Collections we actually want to instance
756  * (ignoring duplicates). */
758  space_outliner, &space_outliner->tree, 0, TSE_SELECTED, collection_find_data_to_edit, &data);
759 
760  /* Find an active collection to add to, that doesn't give dependency cycles. */
761  LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer);
762 
763  GSetIterator collections_to_edit_iter;
764  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
765  Collection *collection = reinterpret_cast<Collection *>(
766  BLI_gsetIterator_getKey(&collections_to_edit_iter));
767 
768  while (BKE_collection_cycle_find(active_lc->collection, collection)) {
769  active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc);
770  }
771  }
772 
773  /* Effectively instance the collections. */
774  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
775  Collection *collection = reinterpret_cast<Collection *>(
776  BLI_gsetIterator_getKey(&collections_to_edit_iter));
778  C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, nullptr, false, 0);
779  ob->instance_collection = collection;
781  id_lib_extern(&collection->id);
782  id_us_plus(&collection->id);
783  }
784 
785  BLI_gset_free(data.collections_to_edit, nullptr);
786 
788 
790 
791  return OPERATOR_FINISHED;
792 }
793 
795 {
796  /* identifiers */
797  ot->name = "Instance Collection";
798  ot->idname = "OUTLINER_OT_collection_instance";
799  ot->description = "Instance selected collections to active scene";
800 
801  /* api callbacks */
804 
805  /* flags */
807 }
808 
811 /* -------------------------------------------------------------------- */
816 {
817  CollectionEditData *data = reinterpret_cast<CollectionEditData *>(customdata);
818  TreeStoreElem *tselem = TREESTORE(te);
819 
820  if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) {
821  return TRAVERSE_CONTINUE;
822  }
823 
824  LayerCollection *lc = reinterpret_cast<LayerCollection *>(te->directdata);
825 
826  if (lc->collection->flag & COLLECTION_IS_MASTER) {
827  /* skip - showing warning/error message might be misleading
828  * when deleting multiple collections, so just do nothing */
829  }
830  else {
831  /* Delete, duplicate and link don't edit children, those will come along
832  * with the parents. */
833  BLI_gset_add(data->collections_to_edit, lc);
834  }
835 
836  return TRAVERSE_CONTINUE;
837 }
838 
839 static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
840 {
841  /* Poll function so the right click menu show current state of selected collections. */
842  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
843  if (!(space_outliner && space_outliner->outlinevis == SO_VIEW_LAYER)) {
844  return false;
845  }
846 
849  data.scene = scene;
850  data.space_outliner = space_outliner;
851  data.is_liboverride_allowed = true;
852  data.is_liboverride_hierarchy_root_allowed = true;
853  data.collections_to_edit = BLI_gset_ptr_new(__func__);
854  bool result = false;
855 
856  outliner_tree_traverse(space_outliner,
857  &space_outliner->tree,
858  0,
859  TSE_SELECTED,
861  &data);
862 
863  GSetIterator collections_to_edit_iter;
864  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
865  LayerCollection *lc = reinterpret_cast<LayerCollection *>(
866  BLI_gsetIterator_getKey(&collections_to_edit_iter));
867 
868  if (clear && (lc->flag & flag)) {
869  result = true;
870  }
871  else if (!clear && !(lc->flag & flag)) {
872  result = true;
873  }
874  }
875 
876  BLI_gset_free(data.collections_to_edit, nullptr);
877  return result;
878 }
879 
881 {
883 }
884 
886 {
888 }
889 
891 {
893 }
894 
896 {
898 }
899 
901 {
903 }
904 
906 {
908 }
909 
911 {
912  Main *bmain = CTX_data_main(C);
914  ViewLayer *view_layer = CTX_data_view_layer(C);
915  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
917  data.scene = scene;
918  data.space_outliner = space_outliner;
919  data.is_liboverride_allowed = true;
920  data.is_liboverride_hierarchy_root_allowed = true;
921  bool clear = strstr(op->idname, "clear") != nullptr;
922  int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
923  strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
925 
926  data.collections_to_edit = BLI_gset_ptr_new(__func__);
927 
928  outliner_tree_traverse(space_outliner,
929  &space_outliner->tree,
930  0,
931  TSE_SELECTED,
933  &data);
934 
935  GSetIterator collections_to_edit_iter;
936  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
937  LayerCollection *lc = reinterpret_cast<LayerCollection *>(
938  BLI_gsetIterator_getKey(&collections_to_edit_iter));
940  }
941 
942  BLI_gset_free(data.collections_to_edit, nullptr);
943 
944  BKE_layer_collection_sync(scene, view_layer);
946 
948 
949  return OPERATOR_FINISHED;
950 }
951 
953 {
954  /* identifiers */
955  ot->name = "Disable from View Layer";
956  ot->idname = "OUTLINER_OT_collection_exclude_set";
957  ot->description = "Exclude collection from the active view layer";
958 
959  /* api callbacks */
962 
963  /* flags */
965 }
966 
968 {
969  /* identifiers */
970  ot->name = "Enable in View Layer";
971  ot->idname = "OUTLINER_OT_collection_exclude_clear";
972  ot->description = "Include collection in the active view layer";
973 
974  /* api callbacks */
977 
978  /* flags */
980 }
981 
983 {
984  /* identifiers */
985  ot->name = "Set Holdout";
986  ot->idname = "OUTLINER_OT_collection_holdout_set";
987  ot->description = "Mask collection in the active view layer";
988 
989  /* api callbacks */
992 
993  /* flags */
995 }
996 
998 {
999  /* identifiers */
1000  ot->name = "Clear Holdout";
1001  ot->idname = "OUTLINER_OT_collection_holdout_clear";
1002  ot->description = "Clear masking of collection in the active view layer";
1003 
1004  /* api callbacks */
1007 
1008  /* flags */
1010 }
1011 
1013 {
1014  /* identifiers */
1015  ot->name = "Set Indirect Only";
1016  ot->idname = "OUTLINER_OT_collection_indirect_only_set";
1017  ot->description =
1018  "Set collection to only contribute indirectly (through shadows and reflections) in the view "
1019  "layer";
1020 
1021  /* api callbacks */
1024 
1025  /* flags */
1027 }
1028 
1030 {
1031  /* identifiers */
1032  ot->name = "Clear Indirect Only";
1033  ot->idname = "OUTLINER_OT_collection_indirect_only_clear";
1034  ot->description = "Clear collection contributing only indirectly in the view layer";
1035 
1036  /* api callbacks */
1039 
1040  /* flags */
1042 }
1043 
1046 /* -------------------------------------------------------------------- */
1051 {
1053  ViewLayer *view_layer = CTX_data_view_layer(C);
1054  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1055  const bool extend = RNA_boolean_get(op->ptr, "extend");
1057  data.scene = scene;
1058  data.space_outliner = space_outliner;
1059  data.is_liboverride_allowed = true;
1060  data.is_liboverride_hierarchy_root_allowed = true;
1061  data.collections_to_edit = BLI_gset_ptr_new(__func__);
1062  outliner_tree_traverse(space_outliner,
1063  &space_outliner->tree,
1064  0,
1065  TSE_SELECTED,
1067  &data);
1068 
1069  GSetIterator collections_to_edit_iter;
1070  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1071  LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(
1072  BLI_gsetIterator_getKey(&collections_to_edit_iter));
1073 
1074  if (extend) {
1075  BKE_layer_collection_isolate_global(scene, view_layer, layer_collection, true);
1076  }
1077  else {
1078  PointerRNA ptr;
1079  PropertyRNA *prop = RNA_struct_type_find_property(&RNA_LayerCollection, "hide_viewport");
1080  RNA_pointer_create(&scene->id, &RNA_LayerCollection, layer_collection, &ptr);
1081 
1082  /* We need to flip the value because the isolate flag routine was designed to work from the
1083  * outliner as a callback. That means the collection visibility was set before the callback
1084  * was called. */
1085  const bool value = !RNA_property_boolean_get(&ptr, prop);
1087  scene, view_layer, layer_collection, nullptr, prop, "hide_viewport", value);
1088  break;
1089  }
1090  }
1091  BLI_gset_free(data.collections_to_edit, nullptr);
1092 
1093  BKE_layer_collection_sync(scene, view_layer);
1095 
1097  return OPERATOR_FINISHED;
1098 }
1099 
1100 static int collection_isolate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1101 {
1102  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "extend");
1103  if (!RNA_property_is_set(op->ptr, prop) && (event->modifier & KM_SHIFT)) {
1104  RNA_property_boolean_set(op->ptr, prop, true);
1105  }
1106  return collection_isolate_exec(C, op);
1107 }
1108 
1110 {
1111  /* identifiers */
1112  ot->name = "Isolate Collection";
1113  ot->idname = "OUTLINER_OT_collection_isolate";
1114  ot->description = "Hide all but this collection and its parents";
1115 
1116  /* api callbacks */
1120 
1121  /* flags */
1123 
1124  /* properties */
1125  PropertyRNA *prop = RNA_def_boolean(
1126  ot->srna, "extend", false, "Extend", "Extend current visible collections");
1128 }
1129 
1131 {
1133 }
1134 
1136 {
1138 }
1139 
1141 {
1143  return false;
1144  }
1145  return outliner_active_layer_collection(C) != nullptr;
1146 }
1147 
1149 {
1151  ViewLayer *view_layer = CTX_data_view_layer(C);
1152  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1153  const bool is_inside = strstr(op->idname, "inside") != nullptr;
1154  const bool show = strstr(op->idname, "show") != nullptr;
1156  data.scene = scene;
1157  data.space_outliner = space_outliner;
1158  data.is_liboverride_allowed = true;
1159  data.is_liboverride_hierarchy_root_allowed = true;
1160  data.collections_to_edit = BLI_gset_ptr_new(__func__);
1161 
1162  outliner_tree_traverse(space_outliner,
1163  &space_outliner->tree,
1164  0,
1165  TSE_SELECTED,
1167  &data);
1168 
1169  GSetIterator collections_to_edit_iter;
1170  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1171  LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(
1172  BLI_gsetIterator_getKey(&collections_to_edit_iter));
1173  BKE_layer_collection_set_visible(view_layer, layer_collection, show, is_inside);
1174  }
1175  BLI_gset_free(data.collections_to_edit, nullptr);
1176 
1177  BKE_layer_collection_sync(scene, view_layer);
1179 
1181  return OPERATOR_FINISHED;
1182 }
1183 
1185 {
1186  /* identifiers */
1187  ot->name = "Show Collection";
1188  ot->idname = "OUTLINER_OT_collection_show";
1189  ot->description = "Show the collection in this view layer";
1190 
1191  /* api callbacks */
1194 
1195  /* flags */
1197 }
1198 
1200 {
1201  /* identifiers */
1202  ot->name = "Hide Collection";
1203  ot->idname = "OUTLINER_OT_collection_hide";
1204  ot->description = "Hide the collection in this view layer";
1205 
1206  /* api callbacks */
1209 
1210  /* flags */
1212 }
1213 
1215 {
1216  /* identifiers */
1217  ot->name = "Show Inside Collection";
1218  ot->idname = "OUTLINER_OT_collection_show_inside";
1219  ot->description = "Show all the objects and collections inside the collection";
1220 
1221  /* api callbacks */
1224 
1225  /* flags */
1227 }
1228 
1230 {
1231  /* identifiers */
1232  ot->name = "Hide Inside Collection";
1233  ot->idname = "OUTLINER_OT_collection_hide_inside";
1234  ot->description = "Hide all the objects and collections inside the collection";
1235 
1236  /* api callbacks */
1239 
1240  /* flags */
1242 }
1243 
1246 /* -------------------------------------------------------------------- */
1250 static bool collection_flag_poll(bContext *C, bool clear, int flag)
1251 {
1253  return false;
1254  }
1255 
1257  if (te == nullptr) {
1258  return false;
1259  }
1260 
1262  if (collection == nullptr) {
1263  return false;
1264  }
1265 
1266  if (clear && (collection->flag & flag)) {
1267  return true;
1268  }
1269  if (!clear && !(collection->flag & flag)) {
1270  return true;
1271  }
1272 
1273  return false;
1274 }
1275 
1277 {
1279 }
1280 
1282 {
1284 }
1285 
1287 {
1289 }
1290 
1292 {
1294 }
1295 
1297 {
1298  Main *bmain = CTX_data_main(C);
1300  ViewLayer *view_layer = CTX_data_view_layer(C);
1301  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1302  const bool is_render = strstr(op->idname, "render");
1303  const bool clear = strstr(op->idname, "show") || strstr(op->idname, "enable");
1304  int flag = is_render ? COLLECTION_HIDE_RENDER : COLLECTION_HIDE_VIEWPORT;
1306  data.scene = scene;
1307  data.space_outliner = space_outliner;
1308  data.is_liboverride_allowed = true;
1309  data.is_liboverride_hierarchy_root_allowed = true;
1310  data.collections_to_edit = BLI_gset_ptr_new(__func__);
1311  const bool has_layer_collection = space_outliner->outlinevis == SO_VIEW_LAYER;
1312 
1313  if (has_layer_collection) {
1314  outliner_tree_traverse(space_outliner,
1315  &space_outliner->tree,
1316  0,
1317  TSE_SELECTED,
1319  &data);
1320  GSetIterator collections_to_edit_iter;
1321  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1322  LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(
1323  BLI_gsetIterator_getKey(&collections_to_edit_iter));
1324  Collection *collection = layer_collection->collection;
1325  if (!BKE_id_is_editable(bmain, &collection->id)) {
1326  continue;
1327  }
1328  if (clear) {
1329  collection->flag &= ~flag;
1330  }
1331  else {
1332  collection->flag |= flag;
1333  }
1334 
1335  /* Make sure (at least for this view layer) the collection is visible. */
1336  if (clear && !is_render) {
1337  layer_collection->flag &= ~LAYER_COLLECTION_HIDE;
1338  }
1339  }
1340  BLI_gset_free(data.collections_to_edit, nullptr);
1341  }
1342  else {
1343  outliner_tree_traverse(space_outliner,
1344  &space_outliner->tree,
1345  0,
1346  TSE_SELECTED,
1348  &data);
1349  GSetIterator collections_to_edit_iter;
1350  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1351  Collection *collection = reinterpret_cast<Collection *>(
1352  BLI_gsetIterator_getKey(&collections_to_edit_iter));
1353  if (!BKE_id_is_editable(bmain, &collection->id)) {
1354  continue;
1355  }
1356 
1357  if (clear) {
1358  collection->flag &= ~flag;
1359  }
1360  else {
1361  collection->flag |= flag;
1362  }
1363  }
1364  BLI_gset_free(data.collections_to_edit, nullptr);
1365  }
1366 
1367  BKE_layer_collection_sync(scene, view_layer);
1369 
1370  if (!is_render) {
1372  }
1373 
1375  return OPERATOR_FINISHED;
1376 }
1377 
1379 {
1380  /* identifiers */
1381  ot->name = "Enable Collection";
1382  ot->idname = "OUTLINER_OT_collection_enable";
1383  ot->description = "Enable viewport display in the view layers";
1384 
1385  /* api callbacks */
1388 
1389  /* flags */
1391 }
1392 
1394 {
1395  /* identifiers */
1396  ot->name = "Disable Collection";
1397  ot->idname = "OUTLINER_OT_collection_disable";
1398  ot->description = "Disable viewport display in the view layers";
1399 
1400  /* api callbacks */
1403 
1404  /* flags */
1406 }
1407 
1409 {
1410  /* identifiers */
1411  ot->name = "Enable Collection in Render";
1412  ot->idname = "OUTLINER_OT_collection_enable_render";
1413  ot->description = "Render the collection";
1414 
1415  /* api callbacks */
1418 
1419  /* flags */
1421 }
1422 
1424 {
1425  /* identifiers */
1426  ot->name = "Disable Collection in Render";
1427  ot->idname = "OUTLINER_OT_collection_disable_render";
1428  ot->description = "Do not render this collection";
1429 
1430  /* api callbacks */
1433 
1434  /* flags */
1436 }
1437 
1444 };
1445 
1448 /* -------------------------------------------------------------------- */
1453 {
1454  OutlinerHideEditData *data = reinterpret_cast<OutlinerHideEditData *>(customdata);
1455  TreeStoreElem *tselem = TREESTORE(te);
1456 
1457  if (tselem == nullptr) {
1458  return TRAVERSE_CONTINUE;
1459  }
1460 
1461  if (tselem->type == TSE_LAYER_COLLECTION) {
1462  LayerCollection *lc = reinterpret_cast<LayerCollection *>(te->directdata);
1463 
1464  if (lc->collection->flag & COLLECTION_IS_MASTER) {
1465  /* Skip - showing warning/error message might be misleading
1466  * when deleting multiple collections, so just do nothing. */
1467  }
1468  else {
1469  /* Delete, duplicate and link don't edit children,
1470  * those will come along with the parents. */
1471  BLI_gset_add(data->collections_to_edit, lc);
1472  }
1473  }
1474  else if ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB)) {
1475  Object *ob = (Object *)tselem->id;
1476  Base *base = BKE_view_layer_base_find(data->view_layer, ob);
1477  BLI_gset_add(data->bases_to_edit, base);
1478  }
1479 
1480  return TRAVERSE_CONTINUE;
1481 }
1482 
1484 {
1486  ViewLayer *view_layer = CTX_data_view_layer(C);
1487  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1489  data.scene = scene;
1490  data.view_layer = view_layer;
1491  data.space_outliner = space_outliner;
1492  data.collections_to_edit = BLI_gset_ptr_new("outliner_hide_exec__collections_to_edit");
1493  data.bases_to_edit = BLI_gset_ptr_new("outliner_hide_exec__bases_to_edit");
1494 
1495  outliner_tree_traverse(space_outliner,
1496  &space_outliner->tree,
1497  0,
1498  TSE_SELECTED,
1500  &data);
1501 
1502  GSetIterator collections_to_edit_iter;
1503  GSET_ITER (collections_to_edit_iter, data.collections_to_edit) {
1504  LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(
1505  BLI_gsetIterator_getKey(&collections_to_edit_iter));
1506  BKE_layer_collection_set_visible(view_layer, layer_collection, false, false);
1507  }
1508  BLI_gset_free(data.collections_to_edit, nullptr);
1509 
1510  GSetIterator bases_to_edit_iter;
1511  GSET_ITER (bases_to_edit_iter, data.bases_to_edit) {
1512  Base *base = reinterpret_cast<Base *>(BLI_gsetIterator_getKey(&bases_to_edit_iter));
1513  base->flag |= BASE_HIDDEN;
1514  }
1515  BLI_gset_free(data.bases_to_edit, nullptr);
1516 
1517  BKE_layer_collection_sync(scene, view_layer);
1519 
1521  return OPERATOR_FINISHED;
1522 }
1523 
1525 {
1526  /* identifiers */
1527  ot->name = "Hide";
1528  ot->idname = "OUTLINER_OT_hide";
1529  ot->description = "Hide selected objects and collections";
1530 
1531  /* api callbacks */
1534 
1535  /* flags */
1537 }
1538 
1540 {
1542  ViewLayer *view_layer = CTX_data_view_layer(C);
1543 
1544  /* Unhide all the collections. */
1545  LayerCollection *lc_master = reinterpret_cast<LayerCollection *>(
1546  view_layer->layer_collections.first);
1547  LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) {
1549  }
1550 
1551  /* Unhide all objects. */
1552  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
1553  base->flag &= ~BASE_HIDDEN;
1554  }
1555 
1556  BKE_layer_collection_sync(scene, view_layer);
1558 
1560  return OPERATOR_FINISHED;
1561 }
1562 
1564 {
1565  /* identifiers */
1566  ot->name = "Unhide All";
1567  ot->idname = "OUTLINER_OT_unhide_all";
1568  ot->description = "Unhide all objects and collections";
1569 
1570  /* api callbacks */
1573 
1574  /* flags */
1576 }
1577 
1580 /* -------------------------------------------------------------------- */
1585 {
1587  SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
1588  const short color_tag = RNA_enum_get(op->ptr, "color");
1589 
1590  IDsSelectedData selected{};
1591 
1592  outliner_tree_traverse(space_outliner,
1593  &space_outliner->tree,
1594  0,
1595  TSE_SELECTED,
1597  &selected);
1598 
1599  LISTBASE_FOREACH (LinkData *, link, &selected.selected_array) {
1600  TreeElement *te_selected = (TreeElement *)link->data;
1601 
1602  Collection *collection = outliner_collection_from_tree_element(te_selected);
1603  if (collection == scene->master_collection) {
1604  continue;
1605  }
1606  if (!BKE_id_is_editable(CTX_data_main(C), &collection->id)) {
1607  BKE_report(op->reports, RPT_WARNING, "Can't add a color tag to a linked collection");
1608  continue;
1609  }
1610 
1611  collection->color_tag = color_tag;
1612  };
1613 
1614  BLI_freelistN(&selected.selected_array);
1615 
1617 
1618  return OPERATOR_FINISHED;
1619 }
1620 
1622 {
1623  /* identifiers */
1624  ot->name = "Set Color Tag";
1625  ot->idname = "OUTLINER_OT_collection_color_tag_set";
1626  ot->description = "Set a color tag for the selected collections";
1627 
1628  /* api callbacks */
1631 
1632  /* flags */
1634 
1635  RNA_def_enum(
1636  ot->srna, "color", rna_enum_collection_color_items, COLLECTION_COLOR_NONE, "Color Tag", "");
1637 }
1638 
struct Collection * BKE_collection_add(struct Main *bmain, struct Collection *parent, const char *name)
Definition: collection.c:425
bool BKE_collection_cycle_find(struct Collection *new_ancestor, struct Collection *collection)
Definition: collection.c:1435
bool BKE_collection_child_add(struct Main *bmain, struct Collection *parent, struct Collection *child)
Definition: collection.c:1585
struct Collection * BKE_collection_duplicate(struct Main *bmain, struct Collection *parent, struct Collection *collection, uint duplicate_flags, uint duplicate_options)
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy)
Definition: collection.c:495
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
Definition: context.c:860
struct LayerCollection * CTX_data_layer_collection(const bContext *C)
Definition: context.c:1126
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct wmMsgBus * CTX_wm_message_bus(const bContext *C)
Definition: context.c:770
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
void BKE_layer_collection_set_flag(struct LayerCollection *lc, int flag, bool value)
Definition: layer.c:1854
bool BKE_layer_collection_objects_select(struct ViewLayer *view_layer, struct LayerCollection *lc, bool deselect)
Definition: layer.c:1409
struct LayerCollection * BKE_layer_collection_get_active(struct ViewLayer *view_layer)
Definition: layer.c:636
void BKE_layer_collection_isolate_global(struct Scene *scene, struct ViewLayer *view_layer, struct LayerCollection *lc, bool extend)
Definition: layer.c:1585
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:379
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, bool visible, bool hierarchy)
Definition: layer.c:1791
bool BKE_id_is_editable(const struct Main *bmain, const struct ID *id)
void id_lib_extern(struct ID *id)
Definition: lib_id.c:237
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void id_fake_user_clear(struct ID *id)
Definition: lib_id.c:351
@ LIB_ID_DUPLICATE_IS_ROOT_ID
Definition: BKE_lib_id.h:228
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.c:83
#define BLI_assert(a)
Definition: BLI_assert.h:46
struct GSet GSet
Definition: BLI_ghash.h:340
GSet * BLI_gset_ptr_new(const char *info)
#define GSET_ITER(gs_iter_, gset_)
Definition: BLI_ghash.h:471
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:458
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:969
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:842
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
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 and Library types, which are fundamental for sdna.
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_SELECT
Definition: DNA_ID.h:818
@ ID_RECALC_BASE_FLAGS
Definition: DNA_ID.h:821
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
Definition: DNA_ID.h:581
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ LIB_TAG_INDIRECT
Definition: DNA_ID.h:677
@ LIB_EMBEDDED_DATA
Definition: DNA_ID.h:635
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
#define ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(_id)
Definition: DNA_ID.h:591
@ ID_SCE
Definition: DNA_ID_enums.h:45
@ ID_GR
Definition: DNA_ID_enums.h:65
@ ID_OB
Definition: DNA_ID_enums.h:47
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
#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, 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
Definition: object_add.cc:668
void ED_outliner_select_sync_from_object_tag(struct bContext *C)
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
#define C
Definition: RandGen.cpp:25
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define ND_OB_SELECT
Definition: WM_types.h:390
#define NC_SCENE
Definition: WM_types.h:328
#define ND_LAYER_CONTENT
Definition: WM_types.h:402
#define ND_LAYER
Definition: WM_types.h:398
@ KM_SHIFT
Definition: WM_types.h:238
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
static bool is_inside(int x, int y, int cols, int rows)
Definition: filesel.c:706
#define GS(x)
Definition: iris.c:225
static void clear(Message *msg)
Definition: msgfmt.c:278
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)
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)
void outliner_collection_delete(bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
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:136
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
Definition: rna_access.c:806
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
Definition: rna_access.c:2180
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
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:3493
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
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:3783
short flag
SpaceOutliner * space_outliner
IDTypeEmbeddedOwnerGetFunction owner_get
Definition: BKE_idtype.h:189
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
short flag
Definition: DNA_ID.h:383
char name[66]
Definition: DNA_ID.h:378
ListBase layer_collections
struct Collection * collection
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase collections
Definition: BKE_main.h:189
short transflag
struct Collection * instance_collection
struct Collection * master_collection
View3DCursor cursor
struct TreeElement * parent
ListBase layer_collections
ListBase object_bases
uint8_t modifier
Definition: WM_types.h:693
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
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:3480
wmOperatorType * ot
Definition: wm_files.c:3479
#define WM_msg_publish_rna_prop(mbus, id_, data_, type_, prop_)