diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-03-29 23:41:17 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-03-30 02:03:47 +0300 |
commit | 534916258d619554106f5e8fd6bb62558e8980bc (patch) | |
tree | 0583d5e8668e7c1b92d58cc114df737d69f0cacf | |
parent | 024395170c67a271af36a3f3f17ff2b2edc6a926 (diff) |
Select Grouped: Collection Part I
Use Shift+G > Collection. If there is only one collection, it just selects it,
if there are multiple ones user get to pick which one to select.
This is the same behaviour we have for groups. Note, we only select objects
directly in the collection, not the ones in any nested collection.
Feature suggested by Pablo Vazquez (venomgfx)
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_select.c | 121 |
3 files changed, 122 insertions, 1 deletions
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index ef51452a983..75117ccdce3 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -108,6 +108,7 @@ void OBJECT_OT_select_mirror(struct wmOperatorType *ot); void OBJECT_OT_select_more(struct wmOperatorType *ot); void OBJECT_OT_select_less(struct wmOperatorType *ot); void OBJECT_OT_select_same_group(struct wmOperatorType *ot); +void OBJECT_OT_select_same_collection(struct wmOperatorType *ot); /* object_add.c */ void OBJECT_OT_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 9c198e996af..492eca20006 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -94,6 +94,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_random); WM_operatortype_append(OBJECT_OT_select_all); WM_operatortype_append(OBJECT_OT_select_same_group); + WM_operatortype_append(OBJECT_OT_select_same_collection); WM_operatortype_append(OBJECT_OT_select_by_type); WM_operatortype_append(OBJECT_OT_select_linked); WM_operatortype_append(OBJECT_OT_select_grouped); diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index f416f499b6a..829144dcb93 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -544,7 +544,7 @@ enum { OBJECT_GRPSEL_PARENT = 2, OBJECT_GRPSEL_SIBLINGS = 3, OBJECT_GRPSEL_TYPE = 4, - /*OBJECT_GRPSEL_LAYER = 5,*/ + OBJECT_GRPSEL_COLLECTION = 5, OBJECT_GRPSEL_GROUP = 6, OBJECT_GRPSEL_HOOK = 7, OBJECT_GRPSEL_PASS = 8, @@ -560,6 +560,7 @@ static const EnumPropertyItem prop_select_grouped_types[] = { {OBJECT_GRPSEL_PARENT, "PARENT", 0, "Parent", ""}, {OBJECT_GRPSEL_SIBLINGS, "SIBLINGS", 0, "Siblings", "Shared Parent"}, {OBJECT_GRPSEL_TYPE, "TYPE", 0, "Type", "Shared object type"}, + {OBJECT_GRPSEL_COLLECTION, "COLLECTION", 0, "Collection", "Shared collection"}, {OBJECT_GRPSEL_GROUP, "GROUP", 0, "Group", "Shared group"}, {OBJECT_GRPSEL_HOOK, "HOOK", 0, "Hook", ""}, {OBJECT_GRPSEL_PASS, "PASS", 0, "Pass", "Render pass Index"}, @@ -733,6 +734,70 @@ static bool select_grouped_type(bContext *C, Object *ob) return changed; } +#define COLLECTION_MENU_MAX 24 +static bool select_grouped_collection(bContext *C, Object *ob) /* Select objects in the same collection as the active */ +{ + typedef struct EnumeratedCollection { + struct SceneCollection *collection; + int index; + } EnumeratedCollection; + + bool changed = false; + SceneCollection *collection; + EnumeratedCollection ob_collections[COLLECTION_MENU_MAX]; + int collection_count = 0, i; + uiPopupMenu *pup; + uiLayout *layout; + + i = 0; + FOREACH_SCENE_COLLECTION_BEGIN(CTX_data_scene(C), scene_collection) + { + if (BKE_collection_object_exists(scene_collection, ob)) { + ob_collections[collection_count].index = i; + ob_collections[collection_count].collection = scene_collection; + if (++collection_count >= COLLECTION_MENU_MAX) { + break; + } + } + i++; + } + FOREACH_SCENE_COLLECTION_END; + + if (!collection_count) { + return 0; + } + else if (collection_count == 1) { + collection = ob_collections[0].collection; + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { + if (BKE_collection_object_exists(collection, base->object)) { + ED_object_base_select(base, BA_SELECT); + changed = true; + } + } + } + CTX_DATA_END; + return changed; + } + + /* build the menu. */ + pup = UI_popup_menu_begin(C, IFACE_("Select Collection"), ICON_NONE); + layout = UI_popup_menu_layout(pup); + + for (i = 0; i < collection_count; i++) { + uiItemIntO(layout, + ob_collections[i].collection->name, + ICON_NONE, + "OBJECT_OT_select_same_collection", + "collection_index", + ob_collections[i].index); + } + + UI_popup_menu_end(C, pup); + return changed; /* The operator already handle this! */ +} + static bool select_grouped_index_object(bContext *C, Object *ob) { bool changed = false; @@ -882,6 +947,9 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) case OBJECT_GRPSEL_TYPE: changed |= select_grouped_type(C, ob); break; + case OBJECT_GRPSEL_COLLECTION: + changed |= select_grouped_collection(C, ob); + break; case OBJECT_GRPSEL_GROUP: changed |= select_grouped_group(C, ob); break; @@ -1055,6 +1123,57 @@ void OBJECT_OT_select_same_group(wmOperatorType *ot) RNA_def_string(ot->srna, "group", NULL, MAX_ID_NAME, "Group", "Name of the group to select"); } +/**************************** Select In The Same Collection ****************************/ + +static int object_select_same_collection_exec(bContext *C, wmOperator *op) +{ + SceneCollection *collection; + + /* passthrough if no objects are visible */ + if (CTX_DATA_COUNT(C, visible_bases) == 0) return OPERATOR_PASS_THROUGH; + + int collection_index = RNA_int_get(op->ptr, "collection_index"); + collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); + + if (!collection) { + return OPERATOR_PASS_THROUGH; + } + + CTX_DATA_BEGIN (C, Base *, base, visible_bases) + { + if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { + if (BKE_collection_object_exists(collection, base->object)) { + ED_object_base_select(base, BA_SELECT); + } + } + } + CTX_DATA_END; + + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_select_same_collection(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Select Same Collection"; + ot->description = "Select object in the same collection"; + ot->idname = "OBJECT_OT_select_same_collection"; + + /* api callbacks */ + ot->exec = object_select_same_collection_exec; + ot->poll = objects_selectable_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + prop = RNA_def_int(ot->srna, "collection_index", -1, -1, INT_MAX, + "Collection Index", "Index of the collection to select", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} /**************************** Select Mirror ****************************/ static int object_select_mirror_exec(bContext *C, wmOperator *op) { |