diff options
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d.py | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_lib_override.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lib_override.c | 36 | ||||
-rw-r--r-- | source/blender/editors/object/object_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/object/object_relations.c | 48 | ||||
-rw-r--r-- | source/blender/editors/space_outliner/outliner_tools.c | 56 |
7 files changed, 149 insertions, 0 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 888b4a62139..bbe23bc8bbc 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2191,6 +2191,8 @@ class VIEW3D_MT_object_relations(Menu): layout.operator("object.make_override_library", text="Make Library Override...") + layout.operator("object.convert_proxy_to_override") + layout.operator("object.make_dupli_face") layout.separator() diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 9a5700d2fbd..233a7d6e478 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -49,6 +49,7 @@ struct IDOverrideLibraryPropertyOperation; struct Main; struct PointerRNA; struct PropertyRNA; +struct Object; struct Scene; struct ViewLayer; @@ -77,6 +78,10 @@ bool BKE_lib_override_library_create(struct Main *bmain, struct ViewLayer *view_layer, struct ID *id_root, struct ID *id_reference); +bool BKE_lib_override_library_proxy_convert(struct Main *bmain, + struct Scene *scene, + struct ViewLayer *view_layer, + struct Object *ob_proxy); bool BKE_lib_override_library_resync(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index d7ccef3c0e7..ec53229057c 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -669,6 +669,42 @@ bool BKE_lib_override_library_create( } /** + * Converts a given proxy object into a library override. + * + * \note This is actually a thin wrapper around \a BKE_lib_override_library_create, only extra work + * is to actually convert the proxy itself into an override first. + * + * \return true if override was successfully created. + */ +bool BKE_lib_override_library_proxy_convert(Main *bmain, + Scene *scene, + ViewLayer *view_layer, + Object *ob_proxy) +{ + /* proxy_group, if defined, is the empty instanciating the collection from which the proxy is + * coming. */ + Object *ob_proxy_group = ob_proxy->proxy_group; + const bool is_override_instancing_object = ob_proxy_group != NULL; + ID *id_root = is_override_instancing_object ? &ob_proxy_group->instance_collection->id : + &ob_proxy->proxy->id; + ID *id_reference = is_override_instancing_object ? &ob_proxy_group->id : &ob_proxy->id; + + /* We manually convert the proxy object into a library override, further override handling will + * then be handled by BKE_lib_override_library_create() just as for a regular override creation. + */ + ob_proxy->proxy->id.tag |= LIB_TAG_DOIT; + ob_proxy->proxy->id.newid = &ob_proxy->id; + BKE_lib_override_library_init(&ob_proxy->id, &ob_proxy->proxy->id); + + ob_proxy->proxy->proxy_from = NULL; + ob_proxy->proxy = ob_proxy->proxy_group = NULL; + + DEG_id_tag_update(&ob_proxy->id, ID_RECALC_COPY_ON_WRITE); + + return BKE_lib_override_library_create(bmain, scene, view_layer, id_root, id_reference); +} + +/** * Advanced 'smart' function to resync, re-create fully functional overrides up-to-date with linked * data, from an existing override hierarchy. * diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 0a243a56dee..d0c6134bab5 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -63,6 +63,7 @@ void OBJECT_OT_track_set(struct wmOperatorType *ot); void OBJECT_OT_track_clear(struct wmOperatorType *ot); void OBJECT_OT_make_local(struct wmOperatorType *ot); void OBJECT_OT_make_override_library(struct wmOperatorType *ot); +void OBJECT_OT_convert_proxy_to_override(struct wmOperatorType *ot); void OBJECT_OT_make_single_user(struct wmOperatorType *ot); void OBJECT_OT_make_links_scene(struct wmOperatorType *ot); void OBJECT_OT_make_links_data(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 390770d5c5c..3fc29f3147b 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -81,6 +81,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_track_clear); WM_operatortype_append(OBJECT_OT_make_local); WM_operatortype_append(OBJECT_OT_make_override_library); + WM_operatortype_append(OBJECT_OT_convert_proxy_to_override); WM_operatortype_append(OBJECT_OT_make_single_user); WM_operatortype_append(OBJECT_OT_make_links_scene); WM_operatortype_append(OBJECT_OT_make_links_data); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 4adf1a8d9f2..9750eff677d 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2490,6 +2490,54 @@ void OBJECT_OT_make_override_library(wmOperatorType *ot) ot->prop = prop; } +static bool convert_proxy_to_override_poll(bContext *C) +{ + Object *obact = CTX_data_active_object(C); + + return obact != NULL && obact->proxy != NULL; +} + +static int convert_proxy_to_override_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + + Object *ob_proxy = CTX_data_active_object(C); + Object *ob_proxy_group = ob_proxy->proxy_group; + const bool is_override_instancing_object = ob_proxy_group != NULL; + + const bool success = BKE_lib_override_library_proxy_convert(bmain, scene, view_layer, ob_proxy); + + /* 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, ob_proxy_group); + } + + DEG_id_tag_update(&CTX_data_scene(C)->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_WINDOW, NULL); + + return success ? OPERATOR_FINISHED : OPERATOR_CANCELLED; +} + +void OBJECT_OT_convert_proxy_to_override(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Convert Proxy To Override"; + ot->description = "Convert a proxy to a local library override"; + ot->idname = "OBJECT_OT_convert_proxy_to_override"; + + /* api callbacks */ + ot->exec = convert_proxy_to_override_exec; + ot->poll = convert_proxy_to_override_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /** \} */ /* ------------------------------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 8fe4c364aa6..eb2969aa15d 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -737,6 +737,31 @@ static void id_local_fn(bContext *C, } } +static void object_proxy_to_override_convert_fn(bContext *C, + ReportList *UNUSED(reports), + Scene *UNUSED(scene), + TreeElement *UNUSED(te), + TreeStoreElem *UNUSED(tsep), + TreeStoreElem *tselem, + void *UNUSED(user_data)) +{ + BLI_assert(TSE_IS_REAL_ID(tselem)); + ID *id_proxy = tselem->id; + BLI_assert(GS(id_proxy->name) == ID_OB); + Object *ob_proxy = (Object *)id_proxy; + Scene *scene = CTX_data_scene(C); + + if (ob_proxy->proxy == NULL) { + return; + } + + BKE_lib_override_library_proxy_convert( + CTX_data_main(C), scene, CTX_data_view_layer(C), ob_proxy); + + DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS | ID_RECALC_COPY_ON_WRITE); + WM_event_add_notifier(C, NC_WINDOW, NULL); +} + typedef struct OutlinerLibOverrideData { bool do_hierarchy; } OutlinerLibOverrideData; @@ -1404,6 +1429,7 @@ enum { OL_OP_RENAME, OL_OP_OBJECT_MODE_ENTER, OL_OP_OBJECT_MODE_EXIT, + OL_OP_PROXY_TO_OVERRIDE_CONVERT, }; static const EnumPropertyItem prop_object_op_types[] = { @@ -1418,6 +1444,11 @@ static const EnumPropertyItem prop_object_op_types[] = { {OL_OP_RENAME, "RENAME", 0, "Rename", ""}, {OL_OP_OBJECT_MODE_ENTER, "OBJECT_MODE_ENTER", 0, "Enter Mode", ""}, {OL_OP_OBJECT_MODE_EXIT, "OBJECT_MODE_EXIT", 0, "Exit Mode", ""}, + {OL_OP_PROXY_TO_OVERRIDE_CONVERT, + "OBJECT_PROXY_TO_OVERRIDE", + 0, + "Convert Proxy to Override", + "Convert a Proxy object to a full library override, inclduing all its dependencies"}, {0, NULL, 0, NULL, NULL}, }; @@ -1487,6 +1518,15 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op) C, op->reports, scene, space_outliner, &space_outliner->tree, item_rename_fn); str = "Rename Object"; } + else if (event == OL_OP_PROXY_TO_OVERRIDE_CONVERT) { + outliner_do_object_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + object_proxy_to_override_convert_fn); + str = "Convert Proxy to Override"; + } else { BLI_assert(0); return OPERATOR_CANCELLED; @@ -1654,6 +1694,7 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_LOCAL, OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE, OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY, @@ -1694,6 +1735,11 @@ static const EnumPropertyItem prop_id_op_types[] = { 0, "Add Library Override Hierarchy", "Add a local override of this linked data-block, and its hierarchy of dependencies"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT, + "OVERRIDE_LIBRARY_PROXY_CONVERT", + 0, + "Convert Proxy to Override", + "Convert a Proxy object to a full library override, inclduing all its dependencies"}, {OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, "OVERRIDE_LIBRARY_RESET", 0, @@ -1904,6 +1950,16 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Overridden Data Hierarchy"); break; } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_PROXY_CONVERT: { + outliner_do_object_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + object_proxy_to_override_convert_fn); + ED_undo_push(C, "Convert Proxy to Override"); + break; + } case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: { outliner_do_libdata_operation(C, op->reports, |