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:
authorJulian Eisel <julian@blender.org>2020-12-28 00:15:20 +0300
committerJulian Eisel <julian@blender.org>2020-12-28 00:45:41 +0300
commitaa64fd69e733e49317101ea60299f2179830ae95 (patch)
tree5546b93625c908945a6123e27110f55c793e8bc8 /source/blender/blenkernel
parent960a0b892c096965696bbd93d0782001d53c869e (diff)
UI: List library overrides in the Outliner
Having a centeral place to find a list of all library overrides should be useful for managing production scenes where library overrides are used a lot. This change adds the individually overridden properties of a data-block under the data-block itself. Just how we show modifiers, constraints or pose channels there. This way we can also expose library override operations/options better in future. There's also a filter option for the library overrides now, so they can be hidden. It is only available in the View Layer display mode though, like the other filter options. One internal change this has to do is adding more informative return values to undo pushes and the library override functions called by it. That way we can send a notifier when library overrides change for the Outliner to know when to rebuild the tree. Differential Revision: https://developer.blender.org/D7631 Reviewed by: Andy Goralczyk, Bastien Montagne, William Reynish
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h6
-rw-r--r--source/blender/blenkernel/BKE_undo_system.h16
-rw-r--r--source/blender/blenkernel/intern/lib_override.c54
-rw-r--r--source/blender/blenkernel/intern/undo_system.c24
4 files changed, 74 insertions, 26 deletions
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 13edabd4cb7..c9a9c26e222 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -95,6 +95,10 @@ struct IDOverrideLibraryProperty *BKE_lib_override_library_property_get(
struct IDOverrideLibrary *override, const char *rna_path, bool *r_created);
void BKE_lib_override_library_property_delete(struct IDOverrideLibrary *override,
struct IDOverrideLibraryProperty *override_property);
+bool BKE_lib_override_rna_property_find(struct PointerRNA *idpoin,
+ const struct IDOverrideLibraryProperty *library_prop,
+ struct PointerRNA *r_override_poin,
+ struct PropertyRNA **r_override_prop);
struct IDOverrideLibraryPropertyOperation *BKE_lib_override_library_property_operation_find(
struct IDOverrideLibraryProperty *override_property,
@@ -131,7 +135,7 @@ bool BKE_lib_override_library_status_check_local(struct Main *bmain, struct ID *
bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct ID *local);
bool BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local);
-void BKE_lib_override_library_main_operations_create(struct Main *bmain, const bool force_auto);
+bool BKE_lib_override_library_main_operations_create(struct Main *bmain, const bool force_auto);
void BKE_lib_override_library_id_reset(struct Main *bmain, struct ID *id_root);
void BKE_lib_override_library_id_hierarchy_reset(struct Main *bmain, struct ID *id_root);
diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h
index 58872d6be58..b13a0580a55 100644
--- a/source/blender/blenkernel/BKE_undo_system.h
+++ b/source/blender/blenkernel/BKE_undo_system.h
@@ -96,6 +96,12 @@ typedef struct UndoStep {
/* Over alloc 'type->struct_size'. */
} UndoStep;
+typedef enum UndoPushReturn {
+ UNDO_PUSH_RET_FAILURE = 0,
+ UNDO_PUSH_RET_SUCCESS = (1 << 0),
+ UNDO_PUSH_RET_OVERRIDE_CHANGED = (1 << 1),
+} UndoPushReturn;
+
typedef void (*UndoTypeForEachIDRefFn)(void *user_data, struct UndoRefID *id_ref);
typedef struct UndoType {
@@ -172,11 +178,11 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack,
const UndoType *ut);
UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, struct bContext *C, const char *name);
-bool BKE_undosys_step_push_with_type(UndoStack *ustack,
- struct bContext *C,
- const char *name,
- const UndoType *ut);
-bool BKE_undosys_step_push(UndoStack *ustack, struct bContext *C, const char *name);
+UndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack,
+ struct bContext *C,
+ const char *name,
+ const UndoType *ut);
+UndoPushReturn BKE_undosys_step_push(UndoStack *ustack, struct bContext *C, const char *name);
UndoStep *BKE_undosys_step_find_by_name_with_type(UndoStack *ustack,
const char *name,
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index cabc80d4024..cb41a4728ef 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -57,6 +57,8 @@
#include "RNA_access.h"
#include "RNA_types.h"
+#include "atomic_ops.h"
+
#define OVERRIDE_AUTO_CHECK_DELAY 0.2 /* 200ms between auto-override checks. */
//#define DEBUG_OVERRIDE_TIMEIT
@@ -982,6 +984,23 @@ IDOverrideLibraryProperty *BKE_lib_override_library_property_get(IDOverrideLibra
return op;
}
+/**
+ * Get the RNA-property matching the \a library_prop override property. Used for UI to query
+ * additional data about the overriden property (e.g. UI name).
+ *
+ * \param idpoin: Pointer to the override ID.
+ * \param library_prop: The library override property to find the matching RNA property for.
+ */
+bool BKE_lib_override_rna_property_find(PointerRNA *idpoin,
+ const IDOverrideLibraryProperty *library_prop,
+ PointerRNA *r_override_poin,
+ PropertyRNA **r_override_prop)
+{
+ BLI_assert(RNA_struct_is_ID(idpoin->type) && ID_IS_OVERRIDE_LIBRARY(idpoin->data));
+ return RNA_path_resolve_property(
+ idpoin, library_prop->rna_path, r_override_poin, r_override_prop);
+}
+
void lib_override_library_property_copy(IDOverrideLibraryProperty *op_dst,
IDOverrideLibraryProperty *op_src)
{
@@ -1370,19 +1389,20 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local)
* since it has to go over all properties in depth (all overridable ones at least).
* Generating differential values and applying overrides are much cheaper.
*
- * \return true if a new overriding op was created, or some local data was reset. */
+ * \return true if any library operation was created.
+ */
bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
{
BLI_assert(local->override_library != NULL);
const bool is_template = (local->override_library->reference == NULL);
- bool ret = false;
+ bool created = false;
if (!is_template) {
/* Do not attempt to generate overriding rules from an empty place-holder generated by link
* code when it cannot find the actual library/ID. Much better to keep the local data-block as
* is in the file in that case, until broken lib is fixed. */
if (ID_MISSING(local->override_library->reference)) {
- return ret;
+ return created;
}
if (GS(local->name) == ID_OB) {
@@ -1412,14 +1432,16 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
local->override_library,
RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE,
&report_flags);
+
if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) {
- ret = true;
+ created = true;
}
+
#ifndef NDEBUG
if (report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORED) {
printf("We did restore some properties of %s from its reference.\n", local->name);
}
- if (ret) {
+ if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) {
printf("We did generate library override rules for %s\n", local->name);
}
else {
@@ -1427,19 +1449,28 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
}
#endif
}
- return ret;
+ return created;
}
+struct LibOverrideOpCreateData {
+ Main *bmain;
+ bool changed;
+};
+
static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, void *taskdata)
{
- Main *bmain = BLI_task_pool_user_data(pool);
+ struct LibOverrideOpCreateData *create_data = BLI_task_pool_user_data(pool);
ID *id = taskdata;
- BKE_lib_override_library_operations_create(bmain, id);
+ if (BKE_lib_override_library_operations_create(create_data->bmain, id)) {
+ /* Technically no need for atomic, all jobs write the same value and we only care if one did
+ * it. But play safe and avoid implicit assumptions. */
+ atomic_fetch_and_or_uint8((uint8_t *)&create_data->changed, true);
+ }
}
/** Check all overrides from given \a bmain and create/update overriding operations as needed. */
-void BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto)
+bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto)
{
ID *id;
@@ -1464,7 +1495,8 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
}
}
- TaskPool *task_pool = BLI_task_pool_create(bmain, TASK_PRIORITY_HIGH);
+ struct LibOverrideOpCreateData create_pool_data = {.bmain = bmain, .changed = false};
+ TaskPool *task_pool = BLI_task_pool_create(&create_pool_data, TASK_PRIORITY_HIGH);
FOREACH_MAIN_ID_BEGIN (bmain, id) {
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) &&
@@ -1503,6 +1535,8 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
#ifdef DEBUG_OVERRIDE_TIMEIT
TIMEIT_END_AVERAGED(BKE_lib_override_library_main_operations_create);
#endif
+
+ return create_pool_data.changed;
}
static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root)
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index b687254fd69..078c93532d9 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -342,9 +342,10 @@ static bool undosys_stack_push_main(UndoStack *ustack, const char *name, struct
CLOG_INFO(&LOG, 1, "'%s'", name);
bContext *C_temp = CTX_create();
CTX_data_main_set(C_temp, bmain);
- bool ok = BKE_undosys_step_push_with_type(ustack, C_temp, name, BKE_UNDOSYS_TYPE_MEMFILE);
+ UndoPushReturn ret = BKE_undosys_step_push_with_type(
+ ustack, C_temp, name, BKE_UNDOSYS_TYPE_MEMFILE);
CTX_free(C_temp);
- return ok;
+ return (ret & UNDO_PUSH_RET_SUCCESS);
}
void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain)
@@ -495,18 +496,21 @@ UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, bContext *C, const char
/**
* \param C: Can be NULL from some callers if their encoding function doesn't need it
*/
-bool BKE_undosys_step_push_with_type(UndoStack *ustack,
- bContext *C,
- const char *name,
- const UndoType *ut)
+UndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack,
+ bContext *C,
+ const char *name,
+ const UndoType *ut)
{
UNDO_NESTED_ASSERT(false);
undosys_stack_validate(ustack, false);
bool is_not_empty = ustack->step_active != NULL;
+ UndoPushReturn retval = UNDO_PUSH_RET_FAILURE;
/* Might not be final place for this to be called - probably only want to call it from some
* undo handlers, not all of them? */
- BKE_lib_override_library_main_operations_create(G_MAIN, false);
+ if (BKE_lib_override_library_main_operations_create(G_MAIN, false)) {
+ retval |= UNDO_PUSH_RET_OVERRIDE_CHANGED;
+ }
/* Remove all undos after (also when 'ustack->step_active == NULL'). */
while (ustack->steps.last != ustack->step_active) {
@@ -558,7 +562,7 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
if (!undosys_step_encode(C, G_MAIN, ustack, us)) {
MEM_freeN(us);
undosys_stack_validate(ustack, true);
- return false;
+ return retval;
}
ustack->step_active = us;
BLI_addtail(&ustack->steps, us);
@@ -589,10 +593,10 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack,
}
undosys_stack_validate(ustack, true);
- return true;
+ return (retval | UNDO_PUSH_RET_SUCCESS);
}
-bool BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name)
+UndoPushReturn BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char *name)
{
UNDO_NESTED_ASSERT(false);
const UndoType *ut = ustack->step_init ? ustack->step_init->type :