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--source/blender/editors/object/object_relations.c44
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc80
2 files changed, 122 insertions, 2 deletions
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 3ecf86d14ed..b2914e0c01f 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2273,6 +2273,10 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
ID *id_root = NULL;
bool is_override_instancing_object = false;
+ GSet *user_overrides_objects_uuids = BLI_gset_new(
+ BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
+ bool user_overrides_from_selected_objects = false;
+
if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
ID_IS_LINKED(obact->instance_collection)) {
if (!ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection)) {
@@ -2285,6 +2289,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
id_root = &obact->instance_collection->id;
is_override_instancing_object = true;
+ 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);
@@ -2309,16 +2314,53 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
id_root = &collection->id;
+ user_overrides_from_selected_objects = true;
}
/* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
else {
id_root = &obact->id;
+ user_overrides_from_selected_objects = true;
+ }
+
+ if (user_overrides_from_selected_objects) {
+ /* Only selected objects can be 'user overrides'. */
+ FOREACH_SELECTED_OBJECT_BEGIN (view_layer, CTX_wm_view3d(C), ob_iter) {
+ BLI_gset_add(user_overrides_objects_uuids, POINTER_FROM_UINT(ob_iter->id.session_uuid));
+ }
+ FOREACH_SELECTED_OBJECT_END;
+ }
+ else {
+ /* Only armatures inside the root collection (and their children) can be 'user overrides'. */
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN ((Collection *)id_root, ob_iter) {
+ if (ob_iter->type == OB_ARMATURE) {
+ BLI_gset_add(user_overrides_objects_uuids, POINTER_FROM_UINT(ob_iter->id.session_uuid));
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ ID *id_root_override;
const bool success = BKE_lib_override_library_create(
- bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, NULL);
+ bmain, scene, view_layer, NULL, id_root, id_root, &obact->id, &id_root_override);
+
+ /* Define liboverrides from selected/validated objects as user defined. */
+ ID *id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
+ id_iter->override_library->hierarchy_root != id_hierarchy_root_override) {
+ continue;
+ }
+ if (BLI_gset_haskey(user_overrides_objects_uuids,
+ POINTER_FROM_UINT(id_iter->override_library->reference->session_uuid))) {
+ id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
+ }
+ }
+ FOREACH_MAIN_ID_END;
+
+ BLI_gset_free(user_overrides_objects_uuids, NULL);
/* Remove the instance empty from this scene, the items now have an overridden collection
* instead. */
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index fdefcc6133e..4a12eeccb66 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -31,6 +31,7 @@
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
+#include "BLI_set.hh"
#include "BLI_utildefines.h"
#include "BKE_anim_data.h"
@@ -87,6 +88,8 @@ static CLG_LogRef LOG = {"ed.outliner.tools"};
using namespace blender::ed::outliner;
+using blender::Set;
+
/* -------------------------------------------------------------------- */
/** \name ID/Library/Data Set/Un-link Utilities
* \{ */
@@ -755,8 +758,37 @@ struct OutlinerLibOverrideData {
* instead of re-applying relevant existing ID pointer property override operations. Helps
* solving broken overrides while not losing *all* of your overrides. */
bool do_resync_hierarchy_enforce;
+
+ /** The override hierarchy root, when known/created. */
+ ID *id_hierarchy_root_override;
+
+ /** A hash of the selected tree elements' ID 'uuid'. Used to clear 'system override' flags on
+ * their newly-created liboverrides in post-process step of override hierarchy creation. */
+ Set<uint> selected_id_uid;
};
+/* Store 'UUID' of IDs of selected elements in the OUtliner tree, before generating the override
+ * hierarchy. */
+static void id_override_library_create_hierarchy_pre_process_fn(bContext *UNUSED(C),
+ ReportList *UNUSED(reports),
+ Scene *UNUSED(scene),
+ TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep),
+ TreeStoreElem *tselem,
+ void *user_data)
+{
+ BLI_assert(TSE_IS_REAL_ID(tselem));
+
+ OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data);
+ const bool do_hierarchy = data->do_hierarchy;
+ ID *id_root_reference = tselem->id;
+
+ BLI_assert(do_hierarchy);
+ UNUSED_VARS_NDEBUG(do_hierarchy);
+
+ data->selected_id_uid.add(id_root_reference->session_uuid);
+}
+
static void id_override_library_create_fn(bContext *C,
ReportList *reports,
Scene *scene,
@@ -895,6 +927,7 @@ static void id_override_library_create_fn(bContext *C,
return;
}
+ ID *id_root_override = nullptr;
success = BKE_lib_override_library_create(bmain,
CTX_data_scene(C),
CTX_data_view_layer(C),
@@ -902,7 +935,22 @@ static void id_override_library_create_fn(bContext *C,
id_root_reference,
id_hierarchy_root_reference,
id_instance_hint,
- nullptr);
+ &id_root_override);
+
+ BLI_assert(id_root_override != nullptr);
+ BLI_assert(!ID_IS_LINKED(id_root_override));
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root_override));
+ if (ID_IS_LINKED(id_hierarchy_root_reference)) {
+ BLI_assert(
+ id_root_override->override_library->hierarchy_root->override_library->reference ==
+ id_hierarchy_root_reference);
+ data->id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
+ }
+ else {
+ BLI_assert(id_root_override->override_library->hierarchy_root ==
+ id_hierarchy_root_reference);
+ data->id_hierarchy_root_override = id_root_override->override_library->hierarchy_root;
+ }
}
else if (ID_IS_OVERRIDABLE_LIBRARY(id_root_reference)) {
success = BKE_lib_override_library_create_from_id(bmain, id_root_reference, true) != nullptr;
@@ -926,6 +974,27 @@ static void id_override_library_create_fn(bContext *C,
}
}
+/* Clear system override flag from newly created overrides which linked reference were previously
+ * selected in the Outliner tree. */
+static void id_override_library_create_hierarchy_post_process(bContext *C,
+ OutlinerLibOverrideData *data)
+{
+ Main *bmain = CTX_data_main(C);
+ ID *id_hierarchy_root_override = data->id_hierarchy_root_override;
+
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ if (ID_IS_LINKED(id_iter) || !ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) ||
+ id_iter->override_library->hierarchy_root != id_hierarchy_root_override) {
+ continue;
+ }
+ if (data->selected_id_uid.contains(id_iter->override_library->reference->session_uuid)) {
+ id_iter->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED;
+ }
+ }
+ FOREACH_MAIN_ID_END;
+}
+
static void id_override_library_reset_fn(bContext *C,
ReportList *UNUSED(reports),
Scene *UNUSED(scene),
@@ -2092,8 +2161,17 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
scene,
space_outliner,
&space_outliner->tree,
+ id_override_library_create_hierarchy_pre_process_fn,
+ &override_data);
+ outliner_do_libdata_operation(C,
+ op->reports,
+ scene,
+ space_outliner,
+ &space_outliner->tree,
id_override_library_create_fn,
&override_data);
+ id_override_library_create_hierarchy_post_process(C, &override_data);
+
ED_undo_push(C, "Overridden Data Hierarchy");
break;
}