Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py2
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h5
-rw-r--r--source/blender/blenkernel/intern/lib_override.c36
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/object/object_relations.c48
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c56
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,