Collections: Operator to select collection objects
This is only supported by layer collections (the ones accessible in the outliner when you see "View Layer").
This commit is contained in:
parent
26dff781b3
commit
a4d2b102f3
|
@ -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);
|
||||
|
|
|
@ -987,6 +987,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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue