From 9631c1ac1a8ef2e491310778853b912595e6f3ee Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 6 Feb 2018 13:19:52 -0200 Subject: Outliner: Operator to delete outliner selected elements from collection Suggested by Pablo Vazquez (venomgfx). --- .../editors/space_outliner/outliner_collections.c | 75 ++++++++++++++++++++++ .../editors/space_outliner/outliner_intern.h | 8 +++ .../blender/editors/space_outliner/outliner_ops.c | 1 + .../blender/editors/space_outliner/outliner_tree.c | 6 +- 4 files changed, 85 insertions(+), 5 deletions(-) (limited to 'source/blender/editors/space_outliner') diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 89f1240f86d..6897c6a1f83 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -37,6 +37,7 @@ #include "DEG_depsgraph_build.h" #include "DNA_group_types.h" +#include "DNA_object_types.h" #include "ED_screen.h" @@ -563,6 +564,80 @@ void OUTLINER_OT_collection_objects_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int collection_object_remove_poll(bContext *C) +{ + SpaceOops *so = CTX_wm_space_outliner(C); + if (so == NULL) { + return 0; + } + + if ((so->filter & (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)) == + (SO_FILTER_ENABLE | SO_FILTER_NO_COLLECTION)) + { + return 0; + } + + return ELEM(so->outlinevis, SO_VIEW_LAYER, SO_COLLECTIONS, SO_GROUPS); +} + +static int collection_object_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceOops *soops = CTX_wm_space_outliner(C); + Main *bmain = CTX_data_main(C); + + struct ObjectsSelectedData data = { + .objects_selected_array = {NULL, NULL}, + }; + + outliner_tree_traverse(soops, &soops->tree, 0, TSE_SELECTED, outliner_find_selected_objects, &data); + + BLI_LISTBASE_FOREACH (LinkData *, link, &data.objects_selected_array) { + TreeElement *te = (TreeElement *)link->data; + Object *ob = (Object *)TREESTORE(te)->id; + SceneCollection *scene_collection = NULL; + + TreeElement *te_parent = te; + while ((te_parent = te_parent->parent)) { + scene_collection = outliner_scene_collection_from_tree_element(te->parent); + if (scene_collection != NULL) { + break; + } + } + + if (scene_collection != NULL) { + ID *owner_id = TREESTORE(te_parent)->id; + BKE_collection_object_remove(bmain, owner_id, scene_collection, ob, true); + DEG_id_tag_update(owner_id, DEG_TAG_BASE_FLAGS_UPDATE); + } + } + + BLI_freelistN(&data.objects_selected_array); + + outliner_cleanup_tree(soops); + DEG_relations_tag_update(bmain); + + WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +void OUTLINER_OT_collection_object_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Object from Collection"; + ot->idname = "OUTLINER_OT_collection_object_remove"; + ot->description = "Remove selected objects from their respective collection"; + + /* api callbacks */ + ot->exec = collection_object_remove_exec; + ot->poll = collection_object_remove_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + struct CollectionDeleteData { Scene *scene; SpaceOops *soops; diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index aa5b4be44ae..25dcda8f959 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -37,6 +37,7 @@ /* internal exports only */ struct ARegion; +struct ListBase; struct wmOperatorType; struct TreeElement; struct TreeStoreElem; @@ -196,6 +197,12 @@ void outliner_build_tree( struct Scene *scene, struct ViewLayer *view_layer, struct SpaceOops *soops, struct ARegion *ar); +typedef struct ObjectsSelectedData { + struct ListBase objects_selected_array; +} ObjectsSelectedData; + +TreeTraversalAction outliner_find_selected_objects(struct TreeElement *te, void *customdata); + /* outliner_draw.c ---------------------------------------------- */ void draw_outliner(const struct bContext *C); @@ -347,6 +354,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_duplicate(struct wmOperatorType *ot); +void OUTLINER_OT_collection_object_remove(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_remove(struct wmOperatorType *ot); void OUTLINER_OT_collection_objects_select(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c index eb42fe47cbf..0734c3f9701 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_nested_new); WM_operatortype_append(OUTLINER_OT_collection_delete_selected); WM_operatortype_append(OUTLINER_OT_collection_objects_add); + WM_operatortype_append(OUTLINER_OT_collection_object_remove); WM_operatortype_append(OUTLINER_OT_collection_objects_remove); WM_operatortype_append(OUTLINER_OT_collection_objects_select); } diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index d3323839b34..e2bd4c5672c 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -423,11 +423,7 @@ static void outliner_add_scene_contents( #endif } -struct ObjectsSelectedData { - ListBase objects_selected_array; -}; - -static TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) +TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) { struct ObjectsSelectedData *data = customdata; TreeStoreElem *tselem = TREESTORE(te); -- cgit v1.2.3