diff options
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r-- | source/blender/editors/object/object_add.c | 83 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 107 | ||||
-rw-r--r-- | source/blender/editors/object/object_group.c | 272 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 24 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 34 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 200 | ||||
-rw-r--r-- | source/blender/editors/object/object_select.c | 166 | ||||
-rw-r--r-- | source/blender/editors/object/object_transform.c | 4 |
8 files changed, 411 insertions, 479 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index d9c743aaf27..8d64d8b67e9 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -71,7 +71,6 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_font.h" -#include "BKE_group.h" #include "BKE_lamp.h" #include "BKE_lattice.h" #include "BKE_layer.h" @@ -1048,11 +1047,11 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot) ED_object_add_generic_props(ot, false); } -/********************* Add Group Instance Operator ********************/ +/********************* Add Collection Instance Operator ********************/ -static int group_instance_add_exec(bContext *C, wmOperator *op) +static int collection_instance_add_exec(bContext *C, wmOperator *op) { - Group *group; + Collection *collection; unsigned int layer; float loc[3], rot[3]; @@ -1060,7 +1059,7 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) char name[MAX_ID_NAME - 2]; RNA_string_get(op->ptr, "name", name); - group = (Group *)BKE_libblock_find_name(ID_GR, name); + collection = (Collection *)BKE_libblock_find_name(ID_GR, name); if (0 == RNA_struct_property_is_set(op->ptr, "location")) { const wmEvent *event = CTX_wm_window(C)->eventstate; @@ -1073,22 +1072,30 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) } } else - group = BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group")); + collection = BLI_findlink(&CTX_data_main(C)->collection, RNA_enum_get(op->ptr, "collection")); if (!ED_object_add_generic_get_opts(C, op, 'Z', loc, rot, NULL, &layer, NULL)) return OPERATOR_CANCELLED; - if (group) { + if (collection) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Object *ob = ED_object_add_type(C, OB_EMPTY, group->id.name + 2, loc, rot, false, layer); - ob->dup_group = group; - ob->transflag |= OB_DUPLIGROUP; - id_us_plus(&group->id); + ViewLayer *view_layer = CTX_data_view_layer(C); + + /* Avoid dependency cycles. */ + LayerCollection *active_lc = BKE_layer_collection_get_active(view_layer); + while (BKE_collection_find_cycle(active_lc->collection, collection)) { + active_lc = BKE_layer_collection_activate_parent(view_layer, active_lc); + } + + Object *ob = ED_object_add_type(C, OB_EMPTY, collection->id.name + 2, loc, rot, false, layer); + ob->dup_group = collection; + ob->transflag |= OB_DUPLICOLLECTION; + id_us_plus(&collection->id); /* works without this except if you try render right after, see: 22027 */ DEG_relations_tag_update(bmain); - DEG_id_tag_update(&group->id, 0); + DEG_id_tag_update(&collection->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); @@ -1099,27 +1106,27 @@ static int group_instance_add_exec(bContext *C, wmOperator *op) } /* only used as menu */ -void OBJECT_OT_group_instance_add(wmOperatorType *ot) +void OBJECT_OT_collection_instance_add(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name = "Add Group Instance"; - ot->description = "Add a dupligroup instance"; - ot->idname = "OBJECT_OT_group_instance_add"; + ot->name = "Add Collection Instance"; + ot->description = "Add a collection instance"; + ot->idname = "OBJECT_OT_collection_instance_add"; /* api callbacks */ ot->invoke = WM_enum_search_invoke; - ot->exec = group_instance_add_exec; + ot->exec = collection_instance_add_exec; ot->poll = ED_operator_objectmode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Group name to add"); - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); - RNA_def_enum_funcs(prop, RNA_group_itemf); + RNA_def_string(ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Collection name to add"); + prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", ""); + RNA_def_enum_funcs(prop, RNA_collection_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; ED_object_add_generic_props(ot, false); @@ -1197,7 +1204,7 @@ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob) DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE); - BKE_collections_object_remove(bmain, &scene->id, ob, true); + BKE_scene_collections_object_remove(bmain, scene, ob, true); } static int object_delete_exec(bContext *C, wmOperator *op) @@ -1331,7 +1338,7 @@ static void copy_object_set_idnew(bContext *C) /********************* Make Duplicates Real ************************/ /** - * \note regarding hashing dupli-objects when using OB_DUPLIGROUP, skip the first member of #DupliObject.persistent_id + * \note regarding hashing dupli-objects when using OB_DUPLICOLLECTION, skip the first member of #DupliObject.persistent_id * since its a unique index and we only want to know if the group objects are from the same dupli-group instance. */ static unsigned int dupliobject_group_hash(const void *ptr) @@ -1346,7 +1353,7 @@ static unsigned int dupliobject_group_hash(const void *ptr) } /** - * \note regarding hashing dupli-objects when NOT using OB_DUPLIGROUP, include the first member of #DupliObject.persistent_id + * \note regarding hashing dupli-objects when NOT using OB_DUPLICOLLECTION, include the first member of #DupliObject.persistent_id * since its the index of the vertex/face the object is instantiated on and we want to identify objects on the same vertex/face. */ static unsigned int dupliobject_hash(const void *ptr) @@ -1418,7 +1425,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, dupli_gh = BLI_ghash_ptr_new(__func__); if (use_hierarchy) { - if (base->object->transflag & OB_DUPLIGROUP) { + if (base->object->transflag & OB_DUPLICOLLECTION) { parent_gh = BLI_ghash_new(dupliobject_group_hash, dupliobject_group_cmp, __func__); } else { @@ -1438,7 +1445,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, ob_dst->totcol = 0; } - BKE_collection_object_add_from(scene, base->object, ob_dst); + BKE_collection_object_add_from(bmain, scene, base->object, ob_dst); base_dst = BKE_view_layer_base_find(view_layer, ob_dst); BLI_assert(base_dst != NULL); @@ -1492,7 +1499,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, * they won't be read, this is simply for a hash lookup. */ DupliObject dob_key; dob_key.ob = ob_src_par; - if (base->object->transflag & OB_DUPLIGROUP) { + if (base->object->transflag & OB_DUPLICOLLECTION) { memcpy(&dob_key.persistent_id[1], &dob->persistent_id[1], sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1)); @@ -1537,7 +1544,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, } } - if (base->object->transflag & OB_DUPLIGROUP && base->object->dup_group) { + if (base->object->transflag & OB_DUPLICOLLECTION && base->object->dup_group) { for (Object *ob = bmain->object.first; ob; ob = ob->id.next) { if (ob->proxy_group == base->object) { ob->proxy = NULL; @@ -1659,7 +1666,7 @@ static Base *duplibase_for_convert(Main *bmain, Scene *scene, ViewLayer *view_la obn = BKE_object_copy(bmain, ob); DEG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); - BKE_collection_object_add_from(scene, ob, obn); + BKE_collection_object_add_from(bmain, scene, ob, obn); basen = BKE_view_layer_base_find(view_layer, obn); ED_object_base_select(basen, BA_SELECT); @@ -2068,23 +2075,23 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer base = BKE_view_layer_base_find(view_layer, ob); if ((base != NULL) && (base->flag & BASE_VISIBLED)) { - BKE_collection_object_add_from(scene, ob, obn); + BKE_collection_object_add_from(bmain, scene, ob, obn); } else { - LayerCollection *layer_collection = BKE_layer_collection_get_active_ensure(scene, view_layer); - BKE_collection_object_add(&scene->id, layer_collection->scene_collection, obn); + LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer); + BKE_collection_object_add(bmain, layer_collection->collection, obn); } basen = BKE_view_layer_base_find(view_layer, obn); - /* 1) duplis should end up in same group as the original - * 2) Rigid Body sim participants MUST always be part of a group... + /* 1) duplis should end up in same collection as the original + * 2) Rigid Body sim participants MUST always be part of a collection... */ // XXX: is 2) really a good measure here? - if ((ob->flag & OB_FROMGROUP) != 0 || ob->rigidbody_object || ob->rigidbody_constraint) { - Group *group; - for (group = bmain->group.first; group; group = group->id.next) { - if (BKE_group_object_exists(group, ob)) - BKE_group_object_add(group, obn); + if (ob->rigidbody_object || ob->rigidbody_constraint) { + Collection *collection; + for (collection = bmain->collection.first; collection; collection = collection->id.next) { + if (BKE_collection_has_object(collection, ob)) + BKE_collection_object_add(bmain, collection, obn); } } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index b9a7da02611..a2e91761a38 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1506,11 +1506,12 @@ bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_onl static int move_to_collection_exec(bContext *C, wmOperator *op) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); PropertyRNA *prop = RNA_struct_find_property(op->ptr, "collection_index"); - const bool is_add = RNA_boolean_get(op->ptr, "is_add"); + const bool is_link = STREQ(op->idname, "OBJECT_OT_link_to_collection"); const bool is_new = RNA_boolean_get(op->ptr, "is_new"); - SceneCollection *scene_collection; + Collection *collection; if (!RNA_property_is_set(op->ptr, prop)) { BKE_report(op->reports, RPT_ERROR, "No collection selected"); @@ -1518,8 +1519,8 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) } int collection_index = RNA_property_int_get(op->ptr, prop); - scene_collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); - if (scene_collection == NULL) { + collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); + if (collection == NULL) { BKE_report(op->reports, RPT_ERROR, "Unexpected error, collection not found"); return OPERATOR_CANCELLED; } @@ -1540,24 +1541,24 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) if (is_new) { char new_collection_name[MAX_NAME]; RNA_string_get(op->ptr, "new_collection_name", new_collection_name); - scene_collection = BKE_collection_add(&scene->id, scene_collection, COLLECTION_TYPE_NONE, new_collection_name); + collection = BKE_collection_add(bmain, collection, new_collection_name); } if ((single_object != NULL) && - is_add && - BLI_findptr(&scene_collection->objects, single_object, offsetof(LinkData, data))) + is_link && + BLI_findptr(&collection->gobject, single_object, offsetof(CollectionObject, ob))) { - BKE_reportf(op->reports, RPT_ERROR, "%s already in %s", single_object->id.name + 2, scene_collection->name); + BKE_reportf(op->reports, RPT_ERROR, "%s already in %s", single_object->id.name + 2, collection->id.name + 2); return OPERATOR_CANCELLED; } CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { - if (!is_add) { - BKE_collection_object_move(&scene->id, scene_collection, NULL, ob); + if (!is_link) { + BKE_collection_object_move(bmain, scene, collection, NULL, ob); } else { - BKE_collection_object_add(&scene->id, scene_collection, ob); + BKE_collection_object_add(bmain, collection, ob); } } CTX_DATA_END; @@ -1566,8 +1567,8 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) RPT_INFO, "%s %s to %s", (single_object != NULL) ? single_object->id.name + 2 : "Objects", - is_add ? "added" : "moved", - scene_collection->name); + is_link ? "linked" : "moved", + collection->id.name + 2); DEG_relations_tag_update(CTX_data_main(C)); DEG_id_tag_update(&scene->id, 0); @@ -1579,26 +1580,27 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -typedef struct MoveToCollectionData { +struct MoveToCollectionData { struct MoveToCollectionData *next, *prev; int index; - struct SceneCollection *collection; + struct Collection *collection; struct ListBase submenus; PointerRNA ptr; struct wmOperatorType *ot; -} MoveToCollectionData; +}; static int move_to_collection_menus_create(wmOperator *op, MoveToCollectionData *menu) { int index = menu->index; - for (SceneCollection *scene_collection = menu->collection->scene_collections.first; - scene_collection != NULL; - scene_collection = scene_collection->next) + for (CollectionChild *child = menu->collection->children.first; + child != NULL; + child = child->next) { + Collection *collection = child->collection; MoveToCollectionData *submenu = MEM_callocN(sizeof(MoveToCollectionData), "MoveToCollectionData submenu - expected memleak"); BLI_addtail(&menu->submenus, submenu); - submenu->collection = scene_collection; + submenu->collection = collection; submenu->index = ++index; index = move_to_collection_menus_create(op, submenu); submenu->ot = op->type; @@ -1631,11 +1633,19 @@ static void move_to_collection_menus_free(MoveToCollectionData **menu) static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout, void *menu_v) { MoveToCollectionData *menu = menu_v; + const char *name; + + if (menu->collection->flag & COLLECTION_IS_MASTER) { + name = IFACE_("Scene Collection"); + } + else { + name = menu->collection->id.name + 2; + } uiItemIntO(layout, - menu->collection->name, + name, ICON_NONE, - "OBJECT_OT_move_to_collection", + menu->ot->idname, "collection_index", menu->index); uiItemS(layout); @@ -1658,7 +1668,6 @@ static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout "New Collection", ICON_ZOOMIN, menu->ptr.data, - /* We use invoke here so we can read ctrl from event. */ WM_OP_INVOKE_DEFAULT, 0, NULL); @@ -1668,15 +1677,15 @@ static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionDat { if (BLI_listbase_is_empty(&menu->submenus)) { uiItemIntO(layout, - menu->collection->name, + menu->collection->id.name + 2, ICON_NONE, - "OBJECT_OT_move_to_collection", + menu->ot->idname, "collection_index", menu->index); } else { uiItemMenuF(layout, - menu->collection->name, + menu->collection->id.name + 2, ICON_NONE, move_to_collection_menu_create, menu); @@ -1686,8 +1695,10 @@ static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionDat /* This is allocated statically because we need this available for the menus creation callback. */ static MoveToCollectionData *master_collection_menu = NULL; -static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { + Scene *scene = CTX_data_scene(C); + /* Reset the menus data for the current master collection, and free previously allocated data. */ move_to_collection_menus_free(&master_collection_menu); @@ -1695,16 +1706,15 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent prop = RNA_struct_find_property(op->ptr, "collection_index"); if (RNA_property_is_set(op->ptr, prop)) { int collection_index = RNA_property_int_get(op->ptr, prop); - RNA_boolean_set(op->ptr, "is_add", event->ctrl); if (RNA_boolean_get(op->ptr, "is_new")) { prop = RNA_struct_find_property(op->ptr, "new_collection_name"); if (!RNA_property_is_set(op->ptr, prop)) { char name[MAX_NAME]; - SceneCollection *scene_collection; + Collection *collection; - scene_collection = BKE_collection_from_index(CTX_data_scene(C), collection_index); - BKE_collection_new_name_get(&CTX_data_scene(C)->id, scene_collection, name); + collection = BKE_collection_from_index(scene, collection_index); + BKE_collection_new_name_get(collection, name); RNA_property_string_set(op->ptr, prop, name); return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y); @@ -1713,7 +1723,7 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent return move_to_collection_exec(C, op); } - SceneCollection *master_collection = BKE_collection_master(&CTX_data_scene(C)->id); + Collection *master_collection = BKE_collection_master(scene); /* We need the data to be allocated so it's available during menu drawing. * Technically we could use wmOperator->customdata. However there is no free callback @@ -1733,10 +1743,10 @@ static int move_to_collection_invoke(bContext *C, wmOperator *op, const wmEvent uiLayout *layout; /* Build the menus. */ - pup = UI_popup_menu_begin(C, IFACE_("Move to Collection"), ICON_NONE); + const char *title = CTX_IFACE_(op->type->translation_context, op->type->name); + pup = UI_popup_menu_begin(C, title, ICON_NONE); layout = UI_popup_menu_layout(pup); - /* We use invoke here so we can read ctrl from event. */ uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT); move_to_collection_menu_create(C, layout, master_collection_menu); @@ -1752,7 +1762,7 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) /* identifiers */ ot->name = "Move to Collection"; - ot->description = "Move to a collection only (Ctrl to add)"; + ot->description = "Move objects to a scene collection"; ot->idname = "OBJECT_OT_move_to_collection"; /* api callbacks */ @@ -1766,7 +1776,32 @@ void OBJECT_OT_move_to_collection(wmOperatorType *ot) prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX, "Collection Index", "Index of the collection to move to", 0, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); - prop = RNA_def_boolean(ot->srna, "is_add", false, "Add", "Keep object in original collections as well"); + prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); + prop = RNA_def_string(ot->srna, "new_collection_name", NULL, MAX_NAME, "Name", + "Name of the newly added collection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); +} + +void OBJECT_OT_link_to_collection(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Link to Collection"; + ot->description = "Link objects to a collection"; + ot->idname = "OBJECT_OT_link_to_collection"; + + /* api callbacks */ + ot->exec = move_to_collection_exec; + ot->invoke = move_to_collection_invoke; + ot->poll = ED_operator_object_active_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + prop = RNA_def_int(ot->srna, "collection_index", COLLECTION_INVALID_INDEX, COLLECTION_INVALID_INDEX, INT_MAX, + "Collection Index", "Index of the collection to move to", 0, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); prop = RNA_def_boolean(ot->srna, "is_new", false, "New", "Move objects to a new collection"); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c index cb0fbdda970..0a6a81d99da 100644 --- a/source/blender/editors/object/object_group.c +++ b/source/blender/editors/object/object_group.c @@ -39,8 +39,8 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_collection.h" #include "BKE_context.h" -#include "BKE_group.h" #include "BKE_library.h" #include "BKE_library_remap.h" #include "BKE_main.h" @@ -64,8 +64,9 @@ /********************* 3d view operators ***********************/ /* can be called with C == NULL */ -static const EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +static const EnumPropertyItem *collection_object_active_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) { + Main *bmain = CTX_data_main(C); Object *ob; EnumPropertyItem *item = NULL, item_tmp = {0}; int totitem = 0; @@ -78,25 +79,25 @@ static const EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA /* check that the object exists */ if (ob) { - Group *group; + Collection *collection; int i = 0, count = 0; - /* if 2 or more groups, add option to add to all groups */ - group = NULL; - while ((group = BKE_group_object_find(group, ob))) + /* if 2 or more collections, add option to add to all collections */ + collection = NULL; + while ((collection = BKE_collection_object_find(bmain, collection, ob))) count++; if (count >= 2) { - item_tmp.identifier = item_tmp.name = "All Groups"; + item_tmp.identifier = item_tmp.name = "All Collections"; item_tmp.value = INT_MAX; /* this will give NULL on lookup */ RNA_enum_item_add(&item, &totitem, &item_tmp); RNA_enum_item_add_separator(&item, &totitem); } - /* add groups */ - group = NULL; - while ((group = BKE_group_object_find(group, ob))) { - item_tmp.identifier = item_tmp.name = group->id.name + 2; + /* add collections */ + collection = NULL; + while ((collection = BKE_collection_object_find(bmain, collection, ob))) { + item_tmp.identifier = item_tmp.name = collection->id.name + 2; /* item_tmp.icon = ICON_ARMATURE_DATA; */ item_tmp.value = i; RNA_enum_item_add(&item, &totitem, &item_tmp); @@ -110,48 +111,48 @@ static const EnumPropertyItem *group_object_active_itemf(bContext *C, PointerRNA return item; } -/* get the group back from the enum index, quite awkward and UI specific */ -static Group *group_object_active_find_index(Object *ob, const int group_object_index) +/* get the collection back from the enum index, quite awkward and UI specific */ +static Collection *collection_object_active_find_index(Main *bmain, Object *ob, const int collection_object_index) { - Group *group = NULL; + Collection *collection = NULL; int i = 0; - while ((group = BKE_group_object_find(group, ob))) { - if (i == group_object_index) { + while ((collection = BKE_collection_object_find(bmain, collection, ob))) { + if (i == collection_object_index) { break; } i++; } - return group; + return collection; } static int objects_add_active_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); Main *bmain = CTX_data_main(C); - int single_group_index = RNA_enum_get(op->ptr, "group"); - Group *single_group = group_object_active_find_index(ob, single_group_index); - Group *group; + int single_collection_index = RNA_enum_get(op->ptr, "collection"); + Collection *single_collection = collection_object_active_find_index(bmain, ob, single_collection_index); + Collection *collection; bool is_cycle = false; bool updated = false; if (ob == NULL) return OPERATOR_CANCELLED; - /* now add all selected objects to the group(s) */ - for (group = bmain->group.first; group; group = group->id.next) { - if (single_group && group != single_group) + /* now add all selected objects to the collection(s) */ + for (collection = bmain->collection.first; collection; collection = collection->id.next) { + if (single_collection && collection != single_collection) continue; - if (!BKE_group_object_exists(group, ob)) + if (!BKE_collection_has_object(collection, ob)) continue; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - if (BKE_group_object_exists(group, base->object)) + if (BKE_collection_has_object(collection, base->object)) continue; - if (!BKE_group_object_cyclic_check(bmain, base->object, group)) { - BKE_group_object_add(group, base->object); + if (!BKE_collection_object_cyclic_check(bmain, base->object, collection)) { + BKE_collection_object_add(bmain, collection, base->object); updated = true; } else { @@ -162,7 +163,7 @@ static int objects_add_active_exec(bContext *C, wmOperator *op) } if (is_cycle) - BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected"); + BKE_report(op->reports, RPT_WARNING, "Skipped some collections because of cycle detected"); if (!updated) return OPERATOR_CANCELLED; @@ -173,14 +174,14 @@ static int objects_add_active_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GROUP_OT_objects_add_active(wmOperatorType *ot) +void COLLECTION_OT_objects_add_active(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name = "Add Selected To Active Group"; - ot->description = "Add the object to an object group that contains the active object"; - ot->idname = "GROUP_OT_objects_add_active"; + ot->name = "Add Selected To Active Collection"; + ot->description = "Add the object to an object collection that contains the active object"; + ot->idname = "COLLECTION_OT_objects_add_active"; /* api callbacks */ ot->exec = objects_add_active_exec; @@ -191,8 +192,8 @@ void GROUP_OT_objects_add_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to add other selected objects to"); - RNA_def_enum_funcs(prop, group_object_active_itemf); + prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", "The collection to add other selected objects to"); + RNA_def_enum_funcs(prop, collection_object_active_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } @@ -202,26 +203,26 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = OBACT(view_layer); - int single_group_index = RNA_enum_get(op->ptr, "group"); - Group *single_group = group_object_active_find_index(ob, single_group_index); - Group *group; + int single_collection_index = RNA_enum_get(op->ptr, "collection"); + Collection *single_collection = collection_object_active_find_index(bmain, ob, single_collection_index); + Collection *collection; bool ok = false; if (ob == NULL) return OPERATOR_CANCELLED; - /* linking to same group requires its own loop so we can avoid - * looking up the active objects groups each time */ + /* linking to same collection requires its own loop so we can avoid + * looking up the active objects collections each time */ - for (group = bmain->group.first; group; group = group->id.next) { - if (single_group && group != single_group) + for (collection = bmain->collection.first; collection; collection = collection->id.next) { + if (single_collection && collection != single_collection) continue; - if (BKE_group_object_exists(group, ob)) { - /* Remove groups from selected objects */ + if (BKE_collection_has_object(collection, ob)) { + /* Remove collections from selected objects */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - BKE_group_object_unlink(group, base->object); + BKE_collection_object_remove(bmain, collection, base->object, false); ok = 1; } CTX_DATA_END; @@ -229,7 +230,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op) } if (!ok) - BKE_report(op->reports, RPT_ERROR, "Active object contains no groups"); + BKE_report(op->reports, RPT_ERROR, "Active object contains no collections"); DEG_relations_tag_update(bmain); WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL); @@ -237,14 +238,14 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GROUP_OT_objects_remove_active(wmOperatorType *ot) +void COLLECTION_OT_objects_remove_active(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name = "Remove Selected From Active Group"; - ot->description = "Remove the object from an object group that contains the active object"; - ot->idname = "GROUP_OT_objects_remove_active"; + ot->name = "Remove Selected From Active Collection"; + ot->description = "Remove the object from an object collection that contains the active object"; + ot->idname = "COLLECTION_OT_objects_remove_active"; /* api callbacks */ ot->exec = objects_remove_active_exec; @@ -255,19 +256,19 @@ void GROUP_OT_objects_remove_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove other selected objects from"); - RNA_def_enum_funcs(prop, group_object_active_itemf); + prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", "The collection to remove other selected objects from"); + RNA_def_enum_funcs(prop, collection_object_active_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } -static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op)) +static int collection_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - BKE_object_groups_clear(base->object); + BKE_object_groups_clear(bmain, base->object); } CTX_DATA_END; @@ -277,43 +278,43 @@ static int group_objects_remove_all_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -void GROUP_OT_objects_remove_all(wmOperatorType *ot) +void COLLECTION_OT_objects_remove_all(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove From All Groups"; - ot->description = "Remove selected objects from all groups"; - ot->idname = "GROUP_OT_objects_remove_all"; + ot->name = "Remove From All Unlinked Collections"; + ot->description = "Remove selected objects from all collections not used in a scene"; + ot->idname = "COLLECTION_OT_objects_remove_all"; /* api callbacks */ - ot->exec = group_objects_remove_all_exec; + ot->exec = collection_objects_remove_all_exec; ot->poll = ED_operator_objectmode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int group_objects_remove_exec(bContext *C, wmOperator *op) +static int collection_objects_remove_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); Main *bmain = CTX_data_main(C); - int single_group_index = RNA_enum_get(op->ptr, "group"); - Group *single_group = group_object_active_find_index(ob, single_group_index); - Group *group; + int single_collection_index = RNA_enum_get(op->ptr, "collection"); + Collection *single_collection = collection_object_active_find_index(bmain, ob, single_collection_index); + Collection *collection; bool updated = false; if (ob == NULL) return OPERATOR_CANCELLED; - for (group = bmain->group.first; group; group = group->id.next) { - if (single_group && group != single_group) + for (collection = bmain->collection.first; collection; collection = collection->id.next) { + if (single_collection && collection != single_collection) continue; - if (!BKE_group_object_exists(group, ob)) + if (!BKE_collection_has_object(collection, ob)) continue; - /* now remove all selected objects from the group */ + /* now remove all selected objects from the collection */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - BKE_group_object_unlink(group, base->object); + BKE_collection_object_remove(bmain, collection, base->object, false); updated = true; } CTX_DATA_END; @@ -328,17 +329,17 @@ static int group_objects_remove_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GROUP_OT_objects_remove(wmOperatorType *ot) +void COLLECTION_OT_objects_remove(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name = "Remove From Group"; - ot->description = "Remove selected objects from a group"; - ot->idname = "GROUP_OT_objects_remove"; + ot->name = "Remove From Collection"; + ot->description = "Remove selected objects from a collection"; + ot->idname = "COLLECTION_OT_objects_remove"; /* api callbacks */ - ot->exec = group_objects_remove_exec; + ot->exec = collection_objects_remove_exec; ot->invoke = WM_menu_invoke; ot->poll = ED_operator_objectmode; @@ -346,25 +347,24 @@ void GROUP_OT_objects_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", "The group to remove this object from"); - RNA_def_enum_funcs(prop, group_object_active_itemf); + prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", "The collection to remove this object from"); + RNA_def_enum_funcs(prop, collection_object_active_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } -static int group_create_exec(bContext *C, wmOperator *op) +static int collection_create_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Group *group = NULL; char name[MAX_ID_NAME - 2]; /* id name */ RNA_string_get(op->ptr, "name", name); - group = BKE_group_add(bmain, name); + Collection *collection = BKE_collection_add(bmain, NULL, name); CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - BKE_group_object_add(group, base->object); + BKE_collection_object_add(bmain, collection, base->object); } CTX_DATA_END; @@ -374,102 +374,101 @@ static int group_create_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void GROUP_OT_create(wmOperatorType *ot) +void COLLECTION_OT_create(wmOperatorType *ot) { /* identifiers */ - ot->name = "Create New Group"; - ot->description = "Create an object group from selected objects"; - ot->idname = "GROUP_OT_create"; + ot->name = "Create New Collection"; + ot->description = "Create an object collection from selected objects"; + ot->idname = "COLLECTION_OT_create"; /* api callbacks */ - ot->exec = group_create_exec; + ot->exec = collection_create_exec; ot->poll = ED_operator_objectmode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_string(ot->srna, "name", "Group", MAX_ID_NAME - 2, "Name", "Name of the new group"); + RNA_def_string(ot->srna, "name", "Collection", MAX_ID_NAME - 2, "Name", "Name of the new collection"); } /****************** properties window operators *********************/ -static int group_add_exec(bContext *C, wmOperator *UNUSED(op)) +static int collection_add_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_context(C); Main *bmain = CTX_data_main(C); - Group *group; if (ob == NULL) return OPERATOR_CANCELLED; - group = BKE_group_add(bmain, "Group"); - BKE_group_object_add(group, ob); + Collection *collection = BKE_collection_add(bmain, NULL, "Collection"); + BKE_collection_object_add(bmain, collection, ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; } -void OBJECT_OT_group_add(wmOperatorType *ot) +void OBJECT_OT_collection_add(wmOperatorType *ot) { /* identifiers */ - ot->name = "Add to Group"; - ot->idname = "OBJECT_OT_group_add"; - ot->description = "Add an object to a new group"; + ot->name = "Add to Collection"; + ot->idname = "OBJECT_OT_collection_add"; + ot->description = "Add an object to a new collection"; /* api callbacks */ - ot->exec = group_add_exec; + ot->exec = collection_add_exec; ot->poll = ED_operator_objectmode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int group_link_exec(bContext *C, wmOperator *op) +static int collection_link_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_context(C); - Group *group = BLI_findlink(&bmain->group, RNA_enum_get(op->ptr, "group")); + Collection *collection = BLI_findlink(&bmain->collection, RNA_enum_get(op->ptr, "collection")); - if (ELEM(NULL, ob, group)) + if (ELEM(NULL, ob, collection)) return OPERATOR_CANCELLED; - /* Early return check, if the object is already in group + /* Early return check, if the object is already in collection * we could skip all the dependency check and just consider * operator is finished. */ - if (BKE_group_object_exists(group, ob)) { + if (BKE_collection_has_object(collection, ob)) { return OPERATOR_FINISHED; } - /* Adding object to group which is used as dupligroup for self is bad idea. + /* Adding object to collection which is used as duplicollection for self is bad idea. * - * It is also bad idea to add object to group which is in group which + * It is also bad idea to add object to collection which is in collection which * contains our current object. */ - if (BKE_group_object_cyclic_check(bmain, ob, group)) { - BKE_report(op->reports, RPT_ERROR, "Could not add the group because of dependency cycle detected"); + if (BKE_collection_object_cyclic_check(bmain, ob, collection)) { + BKE_report(op->reports, RPT_ERROR, "Could not add the collection because of dependency cycle detected"); return OPERATOR_CANCELLED; } - BKE_group_object_add(group, ob); + BKE_collection_object_add(bmain, collection, ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; } -void OBJECT_OT_group_link(wmOperatorType *ot) +void OBJECT_OT_collection_link(wmOperatorType *ot) { PropertyRNA *prop; /* identifiers */ - ot->name = "Link to Group"; - ot->idname = "OBJECT_OT_group_link"; - ot->description = "Add an object to an existing group"; + ot->name = "Link to Collection"; + ot->idname = "OBJECT_OT_collection_link"; + ot->description = "Add an object to an existing collection"; /* api callbacks */ - ot->exec = group_link_exec; + ot->exec = collection_link_exec; ot->invoke = WM_enum_search_invoke; ot->poll = ED_operator_objectmode; @@ -477,36 +476,37 @@ void OBJECT_OT_group_link(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_enum(ot->srna, "group", DummyRNA_NULL_items, 0, "Group", ""); - RNA_def_enum_funcs(prop, RNA_group_local_itemf); + prop = RNA_def_enum(ot->srna, "collection", DummyRNA_NULL_items, 0, "Collection", ""); + RNA_def_enum_funcs(prop, RNA_collection_local_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } -static int group_remove_exec(bContext *C, wmOperator *UNUSED(op)) +static int collection_remove_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); Object *ob = ED_object_context(C); - Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data; + Collection *collection = CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data; - if (!ob || !group) + if (!ob || !collection) return OPERATOR_CANCELLED; - BKE_group_object_unlink(group, ob); + BKE_collection_object_remove(bmain, collection, ob, false); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; } -void OBJECT_OT_group_remove(wmOperatorType *ot) +void OBJECT_OT_collection_remove(wmOperatorType *ot) { /* identifiers */ - ot->name = "Remove Group"; - ot->idname = "OBJECT_OT_group_remove"; - ot->description = "Remove the active object from this group"; + ot->name = "Remove Collection"; + ot->idname = "OBJECT_OT_collection_remove"; + ot->description = "Remove the active object from this collection"; /* api callbacks */ - ot->exec = group_remove_exec; + ot->exec = collection_remove_exec; ot->poll = ED_operator_objectmode; /* flags */ @@ -514,47 +514,47 @@ void OBJECT_OT_group_remove(wmOperatorType *ot) } -static int group_unlink_exec(bContext *C, wmOperator *UNUSED(op)) +static int collection_unlink_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); - Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data; + Collection *collection = CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data; - if (!group) + if (!collection) return OPERATOR_CANCELLED; - BKE_libblock_delete(bmain, group); + BKE_libblock_delete(bmain, collection); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); return OPERATOR_FINISHED; } -void OBJECT_OT_group_unlink(wmOperatorType *ot) +void OBJECT_OT_collection_unlink(wmOperatorType *ot) { /* identifiers */ - ot->name = "Unlink Group"; - ot->idname = "OBJECT_OT_group_unlink"; - ot->description = "Unlink the group from all objects"; + ot->name = "Unlink Collection"; + ot->idname = "OBJECT_OT_collection_unlink"; + ot->description = "Unlink the collection from all objects"; /* api callbacks */ - ot->exec = group_unlink_exec; + ot->exec = collection_unlink_exec; ot->poll = ED_operator_objectmode; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select objects in the same group as the active */ +static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select objects in the same collection as the active */ { - Group *group = CTX_data_pointer_get_type(C, "group", &RNA_Group).data; + Collection *collection = CTX_data_pointer_get_type(C, "collection", &RNA_Collection).data; - if (!group) + if (!collection) return OPERATOR_CANCELLED; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { - if (BKE_group_object_exists(group, base->object)) { + if (BKE_collection_has_object_recursive(collection, base->object)) { ED_object_base_select(base, BA_SELECT); } } @@ -566,12 +566,12 @@ static int select_grouped_exec(bContext *C, wmOperator *UNUSED(op)) /* Select o return OPERATOR_FINISHED; } -void OBJECT_OT_grouped_select(wmOperatorType *ot) +void OBJECT_OT_collection_objects_select(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select Grouped"; - ot->idname = "OBJECT_OT_grouped_select"; - ot->description = "Select all objects in group"; + ot->name = "Select Objects in Collection"; + ot->idname = "OBJECT_OT_collection_objects_select"; + ot->description = "Select all objects in collection"; /* api callbacks */ ot->exec = select_grouped_exec; diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index dbb81be124a..445b14982ee 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -88,6 +88,7 @@ void OBJECT_OT_paths_clear(struct wmOperatorType *ot); void OBJECT_OT_forcefield_toggle(struct wmOperatorType *ot); void OBJECT_OT_move_to_collection(struct wmOperatorType *ot); +void OBJECT_OT_link_to_collection(struct wmOperatorType *ot); /* object_select.c */ void OBJECT_OT_select_all(struct wmOperatorType *ot); @@ -99,7 +100,6 @@ void OBJECT_OT_select_grouped(struct wmOperatorType *ot); 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 */ @@ -115,7 +115,7 @@ void OBJECT_OT_lamp_add(struct wmOperatorType *ot); void OBJECT_OT_effector_add(struct wmOperatorType *ot); void OBJECT_OT_camera_add(struct wmOperatorType *ot); void OBJECT_OT_speaker_add(struct wmOperatorType *ot); -void OBJECT_OT_group_instance_add(struct wmOperatorType *ot); +void OBJECT_OT_collection_instance_add(struct wmOperatorType *ot); void OBJECT_OT_duplicates_make_real(struct wmOperatorType *ot); void OBJECT_OT_duplicate(struct wmOperatorType *ot); @@ -134,11 +134,11 @@ void OBJECT_OT_hook_reset(struct wmOperatorType *ot); void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); /* object_group.c */ -void GROUP_OT_create(struct wmOperatorType *ot); -void GROUP_OT_objects_remove_all(struct wmOperatorType *ot); -void GROUP_OT_objects_remove(struct wmOperatorType *ot); -void GROUP_OT_objects_add_active(struct wmOperatorType *ot); -void GROUP_OT_objects_remove_active(struct wmOperatorType *ot); +void COLLECTION_OT_create(struct wmOperatorType *ot); +void COLLECTION_OT_objects_remove_all(struct wmOperatorType *ot); +void COLLECTION_OT_objects_remove(struct wmOperatorType *ot); +void COLLECTION_OT_objects_add_active(struct wmOperatorType *ot); +void COLLECTION_OT_objects_remove_active(struct wmOperatorType *ot); /* object_modifier.c */ int edit_modifier_poll_generic(struct bContext *C, struct StructRNA *rna_type, int obtype_flag); @@ -251,11 +251,11 @@ void OBJECT_OT_shape_key_mirror(struct wmOperatorType *ot); void OBJECT_OT_shape_key_move(struct wmOperatorType *ot); /* object_group.c */ -void OBJECT_OT_group_add(struct wmOperatorType *ot); -void OBJECT_OT_group_link(struct wmOperatorType *ot); -void OBJECT_OT_group_remove(struct wmOperatorType *ot); -void OBJECT_OT_group_unlink(struct wmOperatorType *ot); -void OBJECT_OT_grouped_select(struct wmOperatorType *ot); +void OBJECT_OT_collection_add(struct wmOperatorType *ot); +void OBJECT_OT_collection_link(struct wmOperatorType *ot); +void OBJECT_OT_collection_remove(struct wmOperatorType *ot); +void OBJECT_OT_collection_unlink(struct wmOperatorType *ot); +void OBJECT_OT_collection_objects_select(struct wmOperatorType *ot); /* object_bake.c */ void OBJECT_OT_bake_image(wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index c4c86b3932d..c47d741f818 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -93,7 +93,6 @@ 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); @@ -102,11 +101,11 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_select_more); WM_operatortype_append(OBJECT_OT_select_less); - WM_operatortype_append(GROUP_OT_create); - WM_operatortype_append(GROUP_OT_objects_remove_all); - WM_operatortype_append(GROUP_OT_objects_remove); - WM_operatortype_append(GROUP_OT_objects_add_active); - WM_operatortype_append(GROUP_OT_objects_remove_active); + WM_operatortype_append(COLLECTION_OT_create); + WM_operatortype_append(COLLECTION_OT_objects_remove_all); + WM_operatortype_append(COLLECTION_OT_objects_remove); + WM_operatortype_append(COLLECTION_OT_objects_add_active); + WM_operatortype_append(COLLECTION_OT_objects_remove_active); WM_operatortype_append(OBJECT_OT_delete); WM_operatortype_append(OBJECT_OT_text_add); @@ -120,7 +119,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_add); WM_operatortype_append(OBJECT_OT_add_named); WM_operatortype_append(OBJECT_OT_effector_add); - WM_operatortype_append(OBJECT_OT_group_instance_add); + WM_operatortype_append(OBJECT_OT_collection_instance_add); WM_operatortype_append(OBJECT_OT_metaball_add); WM_operatortype_append(OBJECT_OT_duplicates_make_real); WM_operatortype_append(OBJECT_OT_duplicate); @@ -213,6 +212,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(TRANSFORM_OT_vertex_warp); WM_operatortype_append(OBJECT_OT_move_to_collection); + WM_operatortype_append(OBJECT_OT_link_to_collection); WM_operatortype_append(OBJECT_OT_shape_key_add); WM_operatortype_append(OBJECT_OT_shape_key_remove); @@ -221,11 +221,11 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_shape_key_mirror); WM_operatortype_append(OBJECT_OT_shape_key_move); - WM_operatortype_append(OBJECT_OT_group_add); - WM_operatortype_append(OBJECT_OT_group_link); - WM_operatortype_append(OBJECT_OT_group_remove); - WM_operatortype_append(OBJECT_OT_group_unlink); - WM_operatortype_append(OBJECT_OT_grouped_select); + WM_operatortype_append(OBJECT_OT_collection_add); + WM_operatortype_append(OBJECT_OT_collection_link); + WM_operatortype_append(OBJECT_OT_collection_remove); + WM_operatortype_append(OBJECT_OT_collection_unlink); + WM_operatortype_append(OBJECT_OT_collection_objects_select); WM_operatortype_append(OBJECT_OT_hook_add_selob); WM_operatortype_append(OBJECT_OT_hook_add_newob); @@ -395,11 +395,11 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "ANIM_OT_keyframe_delete_v3d", IKEY, KM_PRESS, KM_ALT, 0); WM_keymap_verify_item(keymap, "ANIM_OT_keying_set_active_set", IKEY, KM_PRESS, KM_CTRL | KM_SHIFT | KM_ALT, 0); - WM_keymap_verify_item(keymap, "GROUP_OT_create", GKEY, KM_PRESS, KM_CTRL, 0); - WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove", GKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); - WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_all", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0); - WM_keymap_verify_item(keymap, "GROUP_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); - WM_keymap_verify_item(keymap, "GROUP_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0); + WM_keymap_verify_item(keymap, "COLLECTION_OT_create", GKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_remove", GKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); + WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_remove_all", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL | KM_ALT, 0); + WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_add_active", GKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0); + WM_keymap_verify_item(keymap, "COLLECTION_OT_objects_remove_active", GKEY, KM_PRESS, KM_SHIFT | KM_ALT, 0); WM_keymap_add_menu(keymap, "VIEW3D_MT_object_specials", WKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index dd919aedabb..c5cf946cfb3 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -70,7 +70,6 @@ #include "BKE_DerivedMesh.h" #include "BKE_displist.h" #include "BKE_global.h" -#include "BKE_group.h" #include "BKE_fcurve.h" #include "BKE_idprop.h" #include "BKE_lamp.h" @@ -329,7 +328,7 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event) } else { /* error.. cannot continue */ - BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or group"); + BKE_report(op->reports, RPT_ERROR, "Can only make proxy for a referenced object or collection"); return OPERATOR_CANCELLED; } @@ -343,7 +342,8 @@ static int make_proxy_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); if (gob->dup_group != NULL) { - Base *base = BLI_findlink(&gob->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, "object")); + const ListBase dup_group_objects = BKE_collection_object_cache_get(gob->dup_group); + Base *base = BLI_findlink(&dup_group_objects, RNA_enum_get(op->ptr, "object")); ob = base->object; } else { @@ -385,8 +385,8 @@ static int make_proxy_exec(bContext *C, wmOperator *op) } /* Generic itemf's for operators that take library args */ -static const EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *r_free) +static const EnumPropertyItem *proxy_collection_object_itemf(bContext *C, PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), bool *r_free) { EnumPropertyItem item_tmp = {0}, *item = NULL; int totitem = 0; @@ -397,13 +397,13 @@ static const EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA return DummyRNA_DEFAULT_items; /* find the object to affect */ - FOREACH_GROUP_OBJECT_BEGIN(ob->dup_group, object) + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(ob->dup_group, object) { item_tmp.identifier = item_tmp.name = object->id.name + 2; item_tmp.value = i++; RNA_enum_item_add(&item, &totitem, &item_tmp); } - FOREACH_GROUP_OBJECT_END; + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; RNA_enum_item_end(&item, &totitem); *r_free = true; @@ -431,8 +431,8 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot) /* properties */ /* XXX, relies on hard coded ID at the moment */ prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Proxy Object", - "Name of lib-linked/grouped object to make a proxy for"); - RNA_def_enum_funcs(prop, proxy_group_object_itemf); + "Name of lib-linked/collection object to make a proxy for"); + RNA_def_enum_funcs(prop, proxy_collection_object_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } @@ -1343,7 +1343,8 @@ static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr)) static int make_links_scene_exec(bContext *C, wmOperator *op) { - Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene")); + Main *bmain = CTX_data_main(C); + Scene *scene_to = BLI_findlink(&bmain->scene, RNA_enum_get(op->ptr, "scene")); if (scene_to == NULL) { BKE_report(op->reports, RPT_ERROR, "Could not find scene"); @@ -1360,10 +1361,10 @@ static int make_links_scene_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - SceneCollection *sc_to = BKE_collection_master(&scene_to->id); + Collection *collection_to = BKE_collection_master(scene_to); CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - BKE_collection_object_add(&scene_to->id, sc_to, base->object); + BKE_collection_object_add(bmain, collection_to, base->object); } CTX_DATA_END; @@ -1379,7 +1380,7 @@ enum { MAKE_LINKS_MATERIALS = 2, MAKE_LINKS_ANIMDATA = 3, MAKE_LINKS_GROUP = 4, - MAKE_LINKS_DUPLIGROUP = 5, + MAKE_LINKS_DUPLICOLLECTION = 5, MAKE_LINKS_MODIFIERS = 6, MAKE_LINKS_FONTS = 7, }; @@ -1400,7 +1401,7 @@ static bool allow_make_links_data(const int type, Object *ob_src, Object *ob_dst break; case MAKE_LINKS_ANIMDATA: case MAKE_LINKS_GROUP: - case MAKE_LINKS_DUPLIGROUP: + case MAKE_LINKS_DUPLICOLLECTION: return true; case MAKE_LINKS_MODIFIERS: if (!ELEM(OB_EMPTY, ob_src->type, ob_dst->type)) { @@ -1424,16 +1425,16 @@ static int make_links_data_exec(bContext *C, wmOperator *op) ID *obdata_id; int a; - /* group */ - LinkNode *ob_groups = NULL; + /* collection */ + LinkNode *ob_collections = NULL; bool is_cycle = false; bool is_lib = false; ob_src = ED_object_active_context(C); - /* avoid searching all groups in source object each time */ + /* avoid searching all collections in source object each time */ if (type == MAKE_LINKS_GROUP) { - ob_groups = BKE_object_groups(ob_src); + ob_collections = BKE_object_groups(bmain, ob_src); } CTX_DATA_BEGIN (C, Base *, base_dst, selected_editable_bases) @@ -1478,15 +1479,15 @@ static int make_links_data_exec(bContext *C, wmOperator *op) break; case MAKE_LINKS_GROUP: { - LinkNode *group_node; + LinkNode *collection_node; - /* first clear groups */ - BKE_object_groups_clear(ob_dst); + /* first clear collections */ + BKE_object_groups_clear(bmain, ob_dst); - /* now add in the groups from the link nodes */ - for (group_node = ob_groups; group_node; group_node = group_node->next) { - if (ob_dst->dup_group != group_node->link) { - BKE_group_object_add(group_node->link, ob_dst); + /* now add in the collections from the link nodes */ + for (collection_node = ob_collections; collection_node; collection_node = collection_node->next) { + if (ob_dst->dup_group != collection_node->link) { + BKE_collection_object_add(bmain, collection_node->link, ob_dst); } else { is_cycle = true; @@ -1494,11 +1495,11 @@ static int make_links_data_exec(bContext *C, wmOperator *op) } break; } - case MAKE_LINKS_DUPLIGROUP: + case MAKE_LINKS_DUPLICOLLECTION: ob_dst->dup_group = ob_src->dup_group; if (ob_dst->dup_group) { id_us_plus(&ob_dst->dup_group->id); - ob_dst->transflag |= OB_DUPLIGROUP; + ob_dst->transflag |= OB_DUPLICOLLECTION; } break; case MAKE_LINKS_MODIFIERS: @@ -1542,12 +1543,12 @@ static int make_links_data_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (type == MAKE_LINKS_GROUP) { - if (ob_groups) { - BLI_linklist_free(ob_groups, NULL); + if (ob_collections) { + BLI_linklist_free(ob_collections, NULL); } if (is_cycle) { - BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected"); + BKE_report(op->reports, RPT_WARNING, "Skipped some collections because of cycle detected"); } } @@ -1595,7 +1596,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) {MAKE_LINKS_MATERIALS, "MATERIAL", 0, "Materials", ""}, {MAKE_LINKS_ANIMDATA, "ANIMATION", 0, "Animation Data", ""}, {MAKE_LINKS_GROUP, "GROUPS", 0, "Group", ""}, - {MAKE_LINKS_DUPLIGROUP, "DUPLIGROUP", 0, "DupliGroup", ""}, + {MAKE_LINKS_DUPLICOLLECTION, "DUPLICOLLECTION", 0, "DupliGroup", ""}, {MAKE_LINKS_MODIFIERS, "MODIFIERS", 0, "Modifiers", ""}, {MAKE_LINKS_FONTS, "FONTS", 0, "Fonts", ""}, {0, NULL, 0, NULL, NULL}}; @@ -1619,19 +1620,11 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot) /**************************** Make Single User ********************************/ -static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, const bool copy_groups) +static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob) { /* base gets copy of object */ Object *obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob)); - if (copy_groups) { - if (ob->flag & OB_FROMGROUP) { - obn->flag |= OB_FROMGROUP; - } - } - else { - /* copy already clears */ - } /* remap gpencil parenting */ if (scene->gpd) { @@ -1647,42 +1640,42 @@ static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, return obn; } -static void libblock_relink_scene_collection(SceneCollection *sc) +static void libblock_relink_collection(Collection *collection) { - for (LinkData *link = sc->objects.first; link; link = link->next) { - BKE_libblock_relink_to_newid(link->data); + for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) { + BKE_libblock_relink_to_newid(&cob->ob->id); } - for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { - libblock_relink_scene_collection(nsc); + for (CollectionChild *child = collection->children.first; child; child = child->next) { + libblock_relink_collection(child->collection); } } -static void single_object_users_scene_collection(Main *bmain, Scene *scene, SceneCollection *sc, const int flag, const bool copy_groups) +static void single_object_users_collection(Main *bmain, Scene *scene, Collection *collection, const int flag, const bool copy_collections) { - for (LinkData *link = sc->objects.first; link; link = link->next) { - Object *ob = link->data; + for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) { + Object *ob = cob->ob; /* an object may be in more than one collection */ if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) { if (!ID_IS_LINKED(ob) && ob->id.us > 1) { - link->data = single_object_users_object(bmain, scene, link->data, copy_groups); + cob->ob = single_object_users_object(bmain, scene, cob->ob); } } } - for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) { - single_object_users_scene_collection(bmain, scene, nsc, flag, copy_groups); + for (CollectionChild *child = collection->children.first; child; child = child->next) { + single_object_users_collection(bmain, scene, child->collection, flag, copy_collections); } } -/* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */ -static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups) +/* Warning, sets ID->newid pointers of objects and collections, but does not clear them. */ +static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_collections) { - Group *group, *groupn; + Collection *collection, *collectionn; /* duplicate all the objects of the scene */ - SceneCollection *msc = BKE_collection_master(&scene->id); - single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups); + Collection *master_collection = BKE_collection_master(scene); + single_object_users_collection(bmain, scene, master_collection, flag, copy_collections); /* loop over ViewLayers and assign the pointers accordingly */ for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) { @@ -1691,40 +1684,39 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in } } - /* duplicate groups that consist entirely of duplicated objects */ - for (group = bmain->group.first; group; group = group->id.next) { - if (copy_groups && group->view_layer->object_bases.first) { + /* duplicate collections that consist entirely of duplicated objects */ + for (collection = bmain->collection.first; collection; collection = collection->id.next) { + if (copy_collections) { bool all_duplicated = true; + bool any_duplicated = false; - FOREACH_GROUP_OBJECT_BEGIN(group, object) - { - if (object->id.newid == NULL) { + for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) { + any_duplicated = true; + if (cob->ob->id.newid == NULL) { all_duplicated = false; break; } } - FOREACH_GROUP_OBJECT_END; - if (all_duplicated) { - groupn = ID_NEW_SET(group, BKE_group_copy(bmain, group)); + if (any_duplicated && all_duplicated) { + // TODO: test if this works, with child collections .. + collectionn = ID_NEW_SET(collection, BKE_collection_copy(bmain, NULL, collection)); - FOREACH_GROUP_BASE_BEGIN(groupn, base) - { - base->object = (Object *)base->object->id.newid; + for (CollectionObject *cob = collectionn->gobject.first; cob; cob = cob->next) { + cob->ob = (Object *)cob->ob->id.newid; } - FOREACH_GROUP_BASE_END } } } - /* group pointers in scene */ + /* collection pointers in scene */ BKE_scene_groups_relink(scene); ID_NEW_REMAP(scene->camera); if (v3d) ID_NEW_REMAP(v3d->camera); - /* object and group pointers */ - libblock_relink_scene_collection(msc); + /* object and collection pointers */ + libblock_relink_collection(master_collection); } /* not an especially efficient function, only added so the single user @@ -1917,9 +1909,9 @@ static void single_mat_users_expand(Main *bmain) } /* used for copying scenes */ -void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bool copy_groups) +void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bool copy_collections) { - single_object_users(bmain, scene, NULL, 0, copy_groups); + single_object_users(bmain, scene, NULL, 0, copy_collections); if (full) { single_obdata_users(bmain, scene, NULL, 0); @@ -2038,7 +2030,7 @@ static void tag_localizable_objects(bContext *C, const int mode) * Instance indirectly referenced zero user objects, * otherwise they're lost on reload, see T40595. */ -static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene, ViewLayer *view_layer, SceneCollection *sc) +static bool make_local_all__instance_indirect_unused(Main *bmain, ViewLayer *view_layer, Collection *collection) { Object *ob; bool changed = false; @@ -2049,7 +2041,7 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene, id_us_plus(&ob->id); - BKE_collection_object_add(&scene->id, sc, ob); + BKE_collection_object_add(bmain, collection, ob); base = BKE_view_layer_base_find(view_layer, ob); base->flag |= BASE_SELECTED; BKE_scene_object_base_flag_sync_from_base(base); @@ -2117,7 +2109,6 @@ static void make_local_material_tag(Material *ma) static int make_local_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); ParticleSystem *psys; Material *ma, ***matarar; const int mode = RNA_enum_get(op->ptr, "type"); @@ -2126,14 +2117,14 @@ static int make_local_exec(bContext *C, wmOperator *op) /* Note: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */ if (mode == MAKE_LOCAL_ALL) { ViewLayer *view_layer = CTX_data_view_layer(C); - SceneCollection *scene_collection = CTX_data_scene_collection(C); + Collection *collection = CTX_data_collection(C); BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); /* De-select so the user can differentiate newly instanced from existing objects. */ BKE_view_layer_base_deselect_all(view_layer); - if (make_local_all__instance_indirect_unused(bmain, scene, view_layer, scene_collection)) { + if (make_local_all__instance_indirect_unused(bmain, view_layer, collection)) { BKE_report(op->reports, RPT_INFO, "Orphan library objects added to the current scene to avoid loss"); } } @@ -2282,7 +2273,7 @@ static int make_override_static_invoke(bContext *C, wmOperator *op, const wmEven } else { /* Error.. cannot continue. */ - BKE_report(op->reports, RPT_ERROR, "Can only make static override for a referenced object or group"); + BKE_report(op->reports, RPT_ERROR, "Can only make static override for a referenced object or collection"); return OPERATOR_CANCELLED; } @@ -2296,23 +2287,24 @@ static int make_override_static_exec(bContext *C, wmOperator *op) bool success = false; if (!ID_IS_LINKED(obact) && obact->dup_group != NULL && ID_IS_LINKED(obact->dup_group)) { - Base *base = BLI_findlink(&obact->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, "object")); - Object *obgroup = obact; + const ListBase dup_collection_objects = BKE_collection_object_cache_get(obact->dup_group); + Base *base = BLI_findlink(&dup_collection_objects, RNA_enum_get(op->ptr, "object")); + Object *obcollection = obact; obact = base->object; - Group *group = obgroup->dup_group; + Collection *collection = obcollection->dup_group; - /* First, we make a static override of the linked group itself. */ - group->id.tag |= LIB_TAG_DOIT; + /* First, we make a static override of the linked collection itself. */ + collection->id.tag |= LIB_TAG_DOIT; - /* Then, we make static override of the whole set of objects in the group. */ - FOREACH_GROUP_OBJECT_BEGIN(group, ob) + /* Then, we make static override of the whole set of objects in the Collection. */ + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, ob) { ob->id.tag |= LIB_TAG_DOIT; } - FOREACH_GROUP_OBJECT_END; + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - /* Then, we make static override of the whole set of objects in the group. */ - FOREACH_GROUP_OBJECT_BEGIN(group, ob) + /* Then, we make static override of the whole set of objects in the collection. */ + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(collection, ob) { if (ob->type == OB_ARMATURE && ob->pose != NULL) { for (bPoseChannel *pchan = ob->pose->chanbase.first; pchan != NULL; pchan = pchan->next) { @@ -2322,25 +2314,25 @@ static int make_override_static_exec(bContext *C, wmOperator *op) } } } - FOREACH_GROUP_OBJECT_END; + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; success = BKE_override_static_create_from_tag(bmain); /* Intantiate our newly overridden objects in scene, if not yet done. */ Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - Group *new_group = (Group *)group->id.newid; - FOREACH_GROUP_OBJECT_BEGIN(new_group, new_ob) + Collection *new_collection = (Collection *)collection->id.newid; + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(new_collection, new_ob) { if (new_ob != NULL && new_ob->id.override_static != NULL && (base = BKE_view_layer_base_find(view_layer, new_ob)) == NULL) { - BKE_collection_object_add_from(scene, obgroup, new_ob); + BKE_collection_object_add_from(bmain, scene, obcollection, new_ob); DEG_id_tag_update_ex(bmain, &new_ob->id, OB_RECALC_OB | DEG_TAG_BASE_FLAGS_UPDATE); - /* parent to 'group' empty */ + /* parent to 'collection' empty */ if (new_ob->parent == NULL) { - new_ob->parent = obgroup; + new_ob->parent = obcollection; } if (new_ob == (Object *)obact->id.newid) { base = BKE_view_layer_base_find(view_layer, new_ob); @@ -2354,10 +2346,10 @@ static int make_override_static_exec(bContext *C, wmOperator *op) BKE_override_static_operations_create(&new_ob->id, true); } } - FOREACH_GROUP_OBJECT_END; + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - /* obgroup is no more dupligroup-ing, it merely parents whole group of overriding instantiated objects. */ - obgroup->dup_group = NULL; + /* obcollection is no more duplicollection-ing, it merely parents whole collection of overriding instantiated objects. */ + obcollection->dup_group = NULL; /* Also, we'd likely want to lock by default things like transformations of implicitly overriden objects? */ @@ -2423,8 +2415,8 @@ void OBJECT_OT_make_override_static(wmOperatorType *ot) /* properties */ PropertyRNA *prop; prop = RNA_def_enum(ot->srna, "object", DummyRNA_DEFAULT_items, 0, "Override Object", - "Name of lib-linked/group object to make an override from"); - RNA_def_enum_funcs(prop, proxy_group_object_itemf); + "Name of lib-linked/collection object to make an override from"); + RNA_def_enum_funcs(prop, proxy_collection_object_itemf); RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); ot->prop = prop; } @@ -2441,16 +2433,16 @@ static int make_single_user_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); View3D *v3d = CTX_wm_view3d(C); /* ok if this is NULL */ const int flag = (RNA_enum_get(op->ptr, "type") == MAKE_SINGLE_USER_SELECTED) ? SELECT : 0; - const bool copy_groups = false; + const bool copy_collections = false; bool update_deps = false; if (RNA_boolean_get(op->ptr, "object")) { if (flag == SELECT) { BKE_view_layer_selected_objects_tag(view_layer, OB_DONE); - single_object_users(bmain, scene, v3d, OB_DONE, copy_groups); + single_object_users(bmain, scene, v3d, OB_DONE, copy_collections); } else { - single_object_users(bmain, scene, v3d, 0, copy_groups); + single_object_users(bmain, scene, v3d, 0, copy_collections); } /* needed since object relationships may have changed */ diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index d0d0418c861..d5e6f08352f 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -50,8 +50,8 @@ #include "BLT_translation.h" +#include "BKE_collection.h" #include "BKE_context.h" -#include "BKE_group.h" #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" @@ -267,12 +267,12 @@ static bool object_select_all_by_material(bContext *C, Material *mat) static bool object_select_all_by_dup_group(bContext *C, Object *ob) { bool changed = false; - Group *dup_group = (ob->transflag & OB_DUPLIGROUP) ? ob->dup_group : NULL; + Collection *dup_group = (ob->transflag & OB_DUPLICOLLECTION) ? ob->dup_group : NULL; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { - Group *dup_group_other = (base->object->transflag & OB_DUPLIGROUP) ? base->object->dup_group : NULL; + Collection *dup_group_other = (base->object->transflag & OB_DUPLICOLLECTION) ? base->object->dup_group : NULL; if (dup_group == dup_group_other) { ED_object_base_select(base, BA_SELECT); changed = true; @@ -475,7 +475,6 @@ enum { OBJECT_GRPSEL_SIBLINGS = 3, OBJECT_GRPSEL_TYPE = 4, OBJECT_GRPSEL_COLLECTION = 5, - OBJECT_GRPSEL_GROUP = 6, OBJECT_GRPSEL_HOOK = 7, OBJECT_GRPSEL_PASS = 8, OBJECT_GRPSEL_COLOR = 9, @@ -490,7 +489,6 @@ static const EnumPropertyItem prop_select_grouped_types[] = { {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"}, {OBJECT_GRPSEL_COLOR, "COLOR", 0, "Color", "Object Color"}, @@ -542,30 +540,30 @@ static bool select_grouped_parent(bContext *C) /* Makes parent active and de-sel } -#define GROUP_MENU_MAX 24 -static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */ +#define COLLECTION_MENU_MAX 24 +static bool select_grouped_collection(bContext *C, Object *ob) /* Select objects in the same group as the active */ { bool changed = false; - Group *group, *ob_groups[GROUP_MENU_MAX]; - int group_count = 0, i; + Collection *collection, *ob_collections[COLLECTION_MENU_MAX]; + int collection_count = 0, i; uiPopupMenu *pup; uiLayout *layout; - for (group = CTX_data_main(C)->group.first; group && group_count < GROUP_MENU_MAX; group = group->id.next) { - if (BKE_group_object_exists(group, ob)) { - ob_groups[group_count] = group; - group_count++; + for (collection = CTX_data_main(C)->collection.first; collection && collection_count < COLLECTION_MENU_MAX; collection = collection->id.next) { + if (BKE_collection_has_object(collection, ob)) { + ob_collections[collection_count] = collection; + collection_count++; } } - if (!group_count) + if (!collection_count) return 0; - else if (group_count == 1) { - group = ob_groups[0]; + else if (collection_count == 1) { + collection = ob_collections[0]; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { if (((base->flag & BASE_SELECTED) == 0) && ((base->flag & BASE_SELECTABLED) != 0)) { - if (BKE_group_object_exists(group, base->object)) { + if (BKE_collection_has_object(collection, base->object)) { ED_object_base_select(base, BA_SELECT); changed = true; } @@ -576,12 +574,12 @@ static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in } /* build the menu. */ - pup = UI_popup_menu_begin(C, IFACE_("Select Group"), ICON_NONE); + pup = UI_popup_menu_begin(C, IFACE_("Select Collection"), ICON_NONE); layout = UI_popup_menu_layout(pup); - for (i = 0; i < group_count; i++) { - group = ob_groups[i]; - uiItemStringO(layout, group->id.name + 2, 0, "OBJECT_OT_select_same_group", "group", group->id.name + 2); + for (i = 0; i < collection_count; i++) { + collection = ob_collections[i]; + uiItemStringO(layout, collection->id.name + 2, 0, "OBJECT_OT_select_same_collection", "collection", collection->id.name + 2); } UI_popup_menu_end(C, pup); @@ -662,60 +660,6 @@ 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; - return BKE_collection_objects_select(CTX_data_view_layer(C), collection); - } - - /* 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; @@ -841,9 +785,6 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) case OBJECT_GRPSEL_COLLECTION: changed |= select_grouped_collection(C, ob); break; - case OBJECT_GRPSEL_GROUP: - changed |= select_grouped_group(C, ob); - break; case OBJECT_GRPSEL_HOOK: changed |= select_grouped_object_hooks(C, ob); break; @@ -960,28 +901,28 @@ void OBJECT_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } -/**************************** Select In The Same Group ****************************/ +/**************************** Select In The Same Collection ****************************/ -static int object_select_same_group_exec(bContext *C, wmOperator *op) +static int object_select_same_collection_exec(bContext *C, wmOperator *op) { - Group *group; - char group_name[MAX_ID_NAME]; + Collection *collection; + char collection_name[MAX_ID_NAME]; /* passthrough if no objects are visible */ if (CTX_DATA_COUNT(C, visible_bases) == 0) return OPERATOR_PASS_THROUGH; - RNA_string_get(op->ptr, "group", group_name); + RNA_string_get(op->ptr, "collection", collection_name); - group = (Group *)BKE_libblock_find_name(ID_GR, group_name); + collection = (Collection *)BKE_libblock_find_name(ID_GR, collection_name); - if (!group) { + 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_group_object_exists(group, base->object)) { + if (BKE_collection_has_object(collection, base->object)) { ED_object_base_select(base, BA_SELECT); } } @@ -993,67 +934,24 @@ static int object_select_same_group_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void OBJECT_OT_select_same_group(wmOperatorType *ot) -{ - - /* identifiers */ - ot->name = "Select Same Group"; - ot->description = "Select object in the same group"; - ot->idname = "OBJECT_OT_select_same_group"; - - /* api callbacks */ - ot->exec = object_select_same_group_exec; - ot->poll = objects_selectable_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - 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; - } - - if (BKE_collection_objects_select(CTX_data_view_layer(C), collection)) { - 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); + RNA_def_string(ot->srna, "collection", NULL, MAX_ID_NAME, "Collection", "Name of the collection to select"); } + /**************************** Select Mirror ****************************/ static int object_select_mirror_exec(bContext *C, wmOperator *op) { diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index a862ef718d2..6b22521eedd 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -879,7 +879,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if (ob->data == NULL) { /* special support for dupligroups */ - if ((ob->transflag & OB_DUPLIGROUP) && ob->dup_group && (ob->dup_group->id.tag & LIB_TAG_DOIT) == 0) { + if ((ob->transflag & OB_DUPLICOLLECTION) && ob->dup_group && (ob->dup_group->id.tag & LIB_TAG_DOIT) == 0) { if (ID_IS_LINKED(ob->dup_group)) { tot_lib_error++; } @@ -1088,7 +1088,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if ((ob_other->flag & OB_DONE) == 0 && ((ob->data && (ob->data == ob_other->data)) || (ob->dup_group == ob_other->dup_group && - (ob->transflag | ob_other->transflag) & OB_DUPLIGROUP))) + (ob->transflag | ob_other->transflag) & OB_DUPLICOLLECTION))) { ob_other->flag |= OB_DONE; DEG_id_tag_update(&ob_other->id, OB_RECALC_OB | OB_RECALC_DATA); |