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:
authorBastien Montagne <bastien@blender.org>2022-03-01 20:02:56 +0300
committerFabian Schempp <fabianschempp@googlemail.com>2022-04-11 01:31:47 +0300
commit926b279be7b14a24e3b9c28d369748defd273370 (patch)
tree1c64798173da224b9e1b49f5a327355693d5edaf /source/blender/editors/space_outliner
parentf0f983bea5f6bf6bd9770d35c9a3f5d85f3c048d (diff)
LibOverride: Implement default 'user override' behavior.
Implement default behavior to decide which overrides remain 'system' ones, and which become 'user editable' ones, when creating hierarchy override from 3DView or the Outliner. 3DView: If from an Empty-instanced collection, only Armature objects in that collection are user overrides. If from a set of selected objects, all overrides created from selected objects are user overrides. Outliner: All override IDs created from selected elements in the Outliner are user overrides. There is one special case: When a collection is selected, and is 'closed' in the outliner, all its inner armature objects are also user overrides. Ref: {T95707}.
Diffstat (limited to 'source/blender/editors/space_outliner')
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc95
1 files changed, 93 insertions, 2 deletions
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index 55196d042ae..8c5e3cd2d15 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,50 @@ 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);
+
+ if (GS(id_root_reference->name) == ID_GR && (tselem->flag & TSE_CLOSED) != 0) {
+ /* If selected element is a (closed) collection, check all of its objects recursively, and also
+ * consider the armature ones as 'selected' (i.e. to not become system overrides). */
+ Collection *root_collection = reinterpret_cast<Collection *>(id_root_reference);
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (root_collection, object_iter) {
+ if (id_root_reference->lib == object_iter->id.lib && object_iter->type == OB_ARMATURE) {
+ printf("Foooo\n");
+ data->selected_id_uid.add(object_iter->id.session_uuid);
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+ }
+}
+
static void id_override_library_create_fn(bContext *C,
ReportList *reports,
Scene *scene,
@@ -775,7 +820,7 @@ static void id_override_library_create_fn(bContext *C,
bool is_override_instancing_object = false;
if (tsep != nullptr && tsep->type == TSE_SOME_ID && tsep->id != nullptr &&
GS(tsep->id->name) == ID_OB && !ID_IS_OVERRIDE_LIBRARY(tsep->id)) {
- Object *ob = (Object *)tsep->id;
+ Object *ob = reinterpret_cast<Object *>(tsep->id);
if (ob->type == OB_EMPTY && &ob->instance_collection->id == id_root_reference) {
BLI_assert(GS(id_root_reference->name) == ID_GR);
/* Empty instantiating the collection we override, we need to pass it to BKE overriding code
@@ -888,6 +933,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),
@@ -895,7 +941,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;
@@ -919,6 +980,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),
@@ -2106,8 +2188,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;
}