diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-02-01 20:53:54 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-02-02 17:25:05 +0300 |
commit | a4d2b102f313b8d427e6ff6066f38cc3a2394628 (patch) | |
tree | 6af63f78564ab08127b134394b7cc9bb29e30bed /source/blender | |
parent | 26dff781b3c13ad21010d595d38baa5b8b6e06a5 (diff) |
Collections: Operator to select collection objects
This is only supported by layer collections (the ones accessible
in the outliner when you see "View Layer").
Diffstat (limited to 'source/blender')
6 files changed, 104 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 10026210d0c..f098a7e7468 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -108,6 +108,8 @@ void BKE_collection_enable(struct ViewLayer *view_layer, struct LayerCollection bool BKE_view_layer_has_collection(struct ViewLayer *view_layer, const struct SceneCollection *sc); bool BKE_scene_has_object(struct Scene *scene, struct Object *ob); +void BKE_layer_collection_objects_select(struct LayerCollection *layer_collection); + /* syncing */ void BKE_layer_sync_new_scene_collection(struct ID *owner_id, const struct SceneCollection *sc_parent, struct SceneCollection *sc); diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 9332bafb256..4333faea863 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -988,6 +988,34 @@ void BKE_layer_collection_resync(const ID *owner_id, const SceneCollection *sc) /* ---------------------------------------------------------------------- */ /** + * Select all the objects of this layer collection + * + * It also select the objects that are in nested collections. + * \note Recursive + */ +void BKE_layer_collection_objects_select(struct LayerCollection *layer_collection) +{ + if ((layer_collection->flag & COLLECTION_DISABLED) || + ((layer_collection->flag & COLLECTION_SELECTABLE) == 0)) + { + return; + } + + for (LinkData *link = layer_collection->object_bases.first; link; link = link->next) { + Base *base = link->data; + if (base->flag & BASE_SELECTABLED) { + base->flag |= BASE_SELECTED; + } + } + + for (LayerCollection *iter = layer_collection->layer_collections.first; iter; iter = iter->next) { + BKE_layer_collection_objects_select(iter); + } +} + +/* ---------------------------------------------------------------------- */ + +/** * Link a collection to a renderlayer * The collection needs to be created separately */ diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 8999555521a..394a7a80b39 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -757,3 +757,65 @@ void OUTLINER_OT_collection_toggle(wmOperatorType *ot) #undef ACTION_TOGGLE #undef ACTION_ENABLE #undef ACTION_DISABLE + +struct CollectionObjectsSelectData { + bool error; + LayerCollection *layer_collection; +}; + +static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata) +{ + struct CollectionObjectsSelectData *data = customdata; + TreeStoreElem *tselem = TREESTORE(te); + + switch (tselem->type) { + case TSE_LAYER_COLLECTION: + data->layer_collection = te->directdata; + return TRAVERSE_BREAK; + case TSE_LAYER_COLLECTION_BASE: + return TRAVERSE_CONTINUE; + default: + return TRAVERSE_SKIP_CHILDS; + } +} + +static LayerCollection *outliner_active_layer_collection(bContext *C) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + + struct CollectionObjectsSelectData data = { + .layer_collection = NULL, + }; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_first_selected_layer_collection, &data); + return data.layer_collection; +} + +static int collection_objects_select_exec(bContext *C, wmOperator *UNUSED(op)) +{ + LayerCollection *layer_collection = outliner_active_layer_collection(C); + + if (layer_collection == NULL) { + return OPERATOR_CANCELLED; + } + + BKE_layer_collection_objects_select(layer_collection); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_objects_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Objects"; + ot->idname = "OUTLINER_OT_collection_objects_select"; + ot->description = "Select all the collection objects"; + + /* api callbacks */ + ot->exec = collection_objects_select_exec; + ot->poll = view_layer_editor_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index b06c9b85eb8..06d06d66326 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -345,6 +345,7 @@ void OUTLINER_OT_collection_link(struct wmOperatorType *ot); void OUTLINER_OT_collection_unlink(struct wmOperatorType *ot); void OUTLINER_OT_collection_new(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_remove(struct wmOperatorType *ot); +void OUTLINER_OT_collection_objects_select(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_add(struct wmOperatorType *ot); void OUTLINER_OT_collection_nested_new(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index 52f27b9708e..b5b4fbbf039 100644 --- a/source/blender/editors/space_outliner/outliner_ops.c +++ b/source/blender/editors/space_outliner/outliner_ops.c @@ -479,6 +479,7 @@ void outliner_operatortypes(void) WM_operatortype_append(OUTLINER_OT_collection_delete_selected); WM_operatortype_append(OUTLINER_OT_collection_objects_add); WM_operatortype_append(OUTLINER_OT_collection_objects_remove); + WM_operatortype_append(OUTLINER_OT_collection_objects_select); } static wmKeyMap *outliner_item_drag_drop_modal_keymap(wmKeyConfig *keyconf) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 40ade8a821d..c4d032e34ee 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -675,6 +675,7 @@ typedef enum eOutliner_PropModifierOps { typedef enum eOutliner_PropCollectionOps { OL_COLLECTION_OP_OBJECTS_ADD = 1, OL_COLLECTION_OP_OBJECTS_REMOVE, + OL_COLLECTION_OP_OBJECTS_SELECT, OL_COLLECTION_OP_COLLECTION_NEW, OL_COLLECTION_OP_COLLECTION_DEL, OL_COLLECTION_OP_COLLECTION_UNLINK, @@ -860,6 +861,10 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene); te->store_elem->flag &= ~TSE_SELECTED; } + else if (event == OL_COLLECTION_OP_OBJECTS_SELECT) { + BKE_layer_collection_objects_select(lc); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene); + } else if (event == OL_COLLECTION_OP_COLLECTION_NEW) { if (GS(id->name) == ID_GR) { BKE_collection_add(id, sc, COLLECTION_TYPE_GROUP_INTERNAL, NULL); @@ -1844,6 +1849,7 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot) static EnumPropertyItem prop_collection_op_types[] = { {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"}, {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"}, + {OL_COLLECTION_OP_OBJECTS_SELECT, "OBJECTS_SELECT", ICON_RESTRICT_SELECT_OFF, "Select Objects", "Selected collection objects"}, {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"}, {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"}, {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"}, @@ -1880,7 +1886,10 @@ static int outliner_collection_operation_invoke(bContext *C, wmOperator *op, con for (int i = 0; i < (ARRAY_SIZE(prop_collection_op_types) - 1); i++, prop++) { if (soops->outlinevis != SO_GROUPS || - !ELEM(prop->value, OL_COLLECTION_OP_COLLECTION_UNLINK, OL_COLLECTION_OP_GROUP_CREATE)) + !ELEM(prop->value, + OL_COLLECTION_OP_OBJECTS_SELECT, + OL_COLLECTION_OP_COLLECTION_UNLINK, + OL_COLLECTION_OP_GROUP_CREATE)) { uiItemEnumO_ptr(layout, ot, NULL, prop->icon, "type", prop->value); } |