diff options
author | Bastien Montagne <bastien@blender.org> | 2022-06-16 16:52:07 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2022-06-16 16:58:40 +0300 |
commit | dce03ecd5c85d8e8e23969ab1dc8bf800cea550e (patch) | |
tree | 5b16028fd3ef22ba103f5f87fbc04a0ee99dec41 /source | |
parent | 798b49109b2959e25f8224cf8bd0e631236fbb37 (diff) |
LibOverride: 3DView: simplification and improvements of override creation.
This commit:
* Removes the popup to choose the root collection when called with a
linked object selected (in typical cases there is only one valid
option, if more then the operator fails and report to the user).
* Ensures that the linked reference of newly overridden collections are
also removed from the ViewLayer (i.e. their local parent collections).
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/object/object_relations.c | 137 |
1 files changed, 74 insertions, 63 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 6cfd322b2e2..f55ffdf0fcd 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2290,27 +2290,19 @@ static int make_override_library_exec(bContext *C, wmOperator *op) user_overrides_from_selected_objects = false; } else if (!make_override_library_object_overridable_check(bmain, obact)) { - const int i = RNA_property_enum_get(op->ptr, op->type->prop); - const uint collection_session_uuid = *((uint *)&i); + const int i = RNA_property_int_get(op->ptr, op->type->prop); + const uint collection_session_uuid = *((const uint *)&i); if (collection_session_uuid == MAIN_ID_SESSION_UUID_UNSET) { BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, - "Active object '%s' is not overridable", + "Could not find an overridable root hierarchy for object '%s'", obact->id.name + 2); return OPERATOR_CANCELLED; } - Collection *collection = BLI_listbase_bytes_find(&bmain->collections, &collection_session_uuid, sizeof(collection_session_uuid), offsetof(ID, session_uuid)); - if (!ID_IS_OVERRIDABLE_LIBRARY(collection)) { - BKE_reportf(op->reports, - RPT_ERROR_INVALID_INPUT, - "Could not find an overridable collection containing object '%s'", - obact->id.name + 2); - return OPERATOR_CANCELLED; - } id_root = &collection->id; user_overrides_from_selected_objects = true; } @@ -2372,10 +2364,36 @@ static int make_override_library_exec(bContext *C, wmOperator *op) BLI_gset_free(user_overrides_objects_uids, NULL); } - /* Remove the instance empty from this scene, the items now have an overridden collection - * instead. */ - if (success && is_override_instancing_object) { - ED_object_base_free_and_unlink(bmain, scene, obact); + if (success) { + if (is_override_instancing_object) { + /* Remove the instance empty from this scene, the items now have an overridden collection + * instead. */ + ED_object_base_free_and_unlink(bmain, scene, obact); + } + else { + /* Remove the found root ID from the view layer. */ + switch (GS(id_root->name)) { + case ID_GR: { + Collection *collection_root = (Collection *)id_root; + LISTBASE_FOREACH_MUTABLE ( + CollectionParent *, collection_parent, &collection_root->parents) { + if (ID_IS_LINKED(collection_parent->collection) || + !BKE_view_layer_has_collection(view_layer, collection_parent->collection)) { + continue; + } + BKE_collection_child_remove(bmain, collection_parent->collection, collection_root); + } + break; + } + case ID_OB: { + /* TODO: Not sure how well we can handle this case, when we don't have the collections as + * reference containers... */ + break; + } + default: + break; + } + } } DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); @@ -2385,10 +2403,11 @@ static int make_override_library_exec(bContext *C, wmOperator *op) } /* Set the object to override. */ -static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *obact = ED_object_active_context(C); /* Sanity checks. */ @@ -2402,16 +2421,37 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve return make_override_library_exec(C, op); } - if (ID_IS_LINKED(obact)) { - /* Show menu with list of directly linked collections containing the active object. */ - WM_enum_search_invoke(C, op, event); + if (!ID_IS_LINKED(obact)) { + BKE_report(op->reports, RPT_ERROR, "Cannot make library override from a local object"); return OPERATOR_CANCELLED; } - /* Error.. cannot continue. */ - BKE_report(op->reports, - RPT_ERROR, - "Can only make library override for a referenced object or collection"); + int potential_root_collections_num = 0; + uint collection_session_uuid = MAIN_ID_SESSION_UUID_UNSET; + LISTBASE_FOREACH (Collection *, collection, &bmain->collections) { + /* Only check for directly linked collections. */ + if (!ID_IS_LINKED(&collection->id) || (collection->id.tag & LIB_TAG_INDIRECT) != 0 || + !BKE_view_layer_has_collection(view_layer, collection)) { + continue; + } + if (BKE_collection_has_object_recursive(collection, obact)) { + if (potential_root_collections_num == 0) { + collection_session_uuid = collection->id.session_uuid; + } + potential_root_collections_num++; + } + } + + if (potential_root_collections_num <= 1) { + RNA_property_int_set(op->ptr, op->type->prop, *((int *)&collection_session_uuid)); + return make_override_library_exec(C, op); + } + + BKE_reportf(op->reports, + RPT_ERROR, + "Too many potential root collections (%d) for the override hierarchy, " + "please use the Outliner instead", + potential_root_collections_num); return OPERATOR_CANCELLED; } @@ -2426,37 +2466,6 @@ static bool make_override_library_poll(bContext *C) !ID_IS_OVERRIDE_LIBRARY(obact)))); } -static const EnumPropertyItem *make_override_collections_of_linked_object_itemf( - bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem item_tmp = {0}, *item = NULL; - int totitem = 0; - - Object *object = ED_object_active_context(C); - Main *bmain = CTX_data_main(C); - - if (!object || !ID_IS_LINKED(object)) { - return DummyRNA_DEFAULT_items; - } - - LISTBASE_FOREACH (Collection *, collection, &bmain->collections) { - /* Only check for directly linked collections. */ - if (!ID_IS_LINKED(&collection->id) || (collection->id.tag & LIB_TAG_INDIRECT) != 0) { - continue; - } - if (BKE_collection_has_object_recursive(collection, object)) { - item_tmp.identifier = item_tmp.name = collection->id.name + 2; - item_tmp.value = *((int *)&collection->id.session_uuid); - RNA_enum_item_add(&item, &totitem, &item_tmp); - } - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - void OBJECT_OT_make_override_library(wmOperatorType *ot) { /* identifiers */ @@ -2474,15 +2483,17 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot) /* properties */ PropertyRNA *prop; - prop = RNA_def_enum(ot->srna, - "collection", - DummyRNA_DEFAULT_items, - MAIN_ID_SESSION_UUID_UNSET, - "Override Collection", - "Name of directly linked collection containing the selected object, to make " - "an override from"); - RNA_def_enum_funcs(prop, make_override_collections_of_linked_object_itemf); - RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE); + prop = RNA_def_int(ot->srna, + "collection", + MAIN_ID_SESSION_UUID_UNSET, + INT_MIN, + INT_MAX, + "Override Collection", + "Session UUID of the directly linked collection containing the selected " + "object, to make an override from", + INT_MIN, + INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); ot->prop = prop; prop = RNA_def_boolean(ot->srna, |