[Bf-blender-cvs] [60b80ce142e] blender-v2.90-release: LibOverride: Add core functions to reset a library override.

Bastien Montagne noreply at git.blender.org
Thu Jul 23 11:45:22 CEST 2020


Commit: 60b80ce142eb181342fc691610b3f42fedc0c00b
Author: Bastien Montagne
Date:   Thu Jul 23 11:30:48 2020 +0200
Branches: blender-v2.90-release
https://developer.blender.org/rB60b80ce142eb181342fc691610b3f42fedc0c00b

LibOverride: Add core functions to reset a library override.

This means that we delete all override properties except for those over
ID pointers *if* the assigned pointer matches the linked data hierarchy.

Then we reload affected datablocks.

===================================================================

M	source/blender/blenkernel/BKE_lib_override.h
M	source/blender/blenkernel/intern/lib_override.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index ba8f2eb3399..6a05f0c22b6 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -119,6 +119,9 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct
 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);
 
+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);
+
 void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
                                              const short tag,
                                              const bool do_set);
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 7577e803adc..421a53b8e8d 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1165,6 +1165,137 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for
 #endif
 }
 
+static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root)
+{
+  bool was_property_deleted = false;
+
+  LISTBASE_FOREACH_MUTABLE (
+      IDOverrideLibraryProperty *, op, &id_root->override_library->properties) {
+    bool do_op_delete = true;
+    const bool is_collection = op->rna_prop_type == PROP_COLLECTION;
+    if (is_collection || op->rna_prop_type == PROP_POINTER) {
+      PointerRNA ptr_root, ptr_root_lib, ptr, ptr_lib;
+      PropertyRNA *prop, *prop_lib;
+
+      RNA_pointer_create(id_root, &RNA_ID, id_root, &ptr_root);
+      RNA_pointer_create(id_root->override_library->reference,
+                         &RNA_ID,
+                         id_root->override_library->reference,
+                         &ptr_root_lib);
+
+      bool prop_exists = RNA_path_resolve_property(&ptr_root, op->rna_path, &ptr, &prop);
+      BLI_assert(prop_exists);
+      prop_exists = RNA_path_resolve_property(&ptr_root_lib, op->rna_path, &ptr_lib, &prop_lib);
+
+      if (prop_exists) {
+        BLI_assert(ELEM(RNA_property_type(prop), PROP_POINTER, PROP_COLLECTION));
+        BLI_assert(RNA_property_type(prop) == RNA_property_type(prop_lib));
+        if (is_collection) {
+          ptr.type = RNA_property_pointer_type(&ptr, prop);
+          ptr_lib.type = RNA_property_pointer_type(&ptr_lib, prop_lib);
+        }
+        else {
+          ptr = RNA_property_pointer_get(&ptr, prop);
+          ptr_lib = RNA_property_pointer_get(&ptr_lib, prop_lib);
+        }
+        if (ptr.owner_id != NULL && ptr_lib.owner_id != NULL) {
+          BLI_assert(ptr.type == ptr_lib.type);
+          do_op_delete = !(RNA_struct_is_ID(ptr.type) && ptr.owner_id->override_library != NULL &&
+                           ptr.owner_id->override_library->reference == ptr_lib.owner_id);
+        }
+      }
+    }
+
+    if (do_op_delete) {
+      BKE_lib_override_library_property_delete(id_root->override_library, op);
+      was_property_deleted = true;
+    }
+  }
+
+  if (was_property_deleted) {
+    DEG_id_tag_update_ex(bmain, id_root, ID_RECALC_COPY_ON_WRITE);
+    IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(
+        id_root->override_library);
+    override_runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+  }
+
+  return was_property_deleted;
+}
+
+/** Reset all overrides in given \a id_root, while preserving ID relations. */
+void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root)
+{
+  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+    return;
+  }
+
+  if (lib_override_library_id_reset_do(bmain, id_root)) {
+    if (id_root->override_library->runtime != NULL &&
+        (id_root->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) !=
+            0) {
+      BKE_lib_override_library_update(bmain, id_root);
+      id_root->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+    }
+  }
+}
+
+static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root)
+{
+  if (!ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) {
+    return;
+  }
+
+  void **entry_pp = BLI_ghash_lookup(bmain->relations->id_user_to_used, id_root);
+  if (entry_pp == NULL) {
+    /* Already processed. */
+    return;
+  }
+
+  lib_override_library_id_reset_do(bmain, id_root);
+
+  /* This way we won't process again that ID should we encounter it again through another
+   * relationship hierarchy.
+   * Note that this does not free any memory from relations, so we can still use the entries.
+   */
+  BKE_main_relations_ID_remove(bmain, id_root);
+
+  for (MainIDRelationsEntry *entry = *entry_pp; entry != NULL; entry = entry->next) {
+    if ((entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
+      /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
+       * actual dependencies. */
+      continue;
+    }
+    /* We only consider IDs from the same library. */
+    if (entry->id_pointer != NULL) {
+      ID *id_entry = *entry->id_pointer;
+      if (id_entry->override_library != NULL) {
+        lib_override_library_id_hierarchy_recursive_reset(bmain, id_entry);
+      }
+    }
+  }
+}
+
+/** Reset all overrides in given \a id_root and its dependencies, while preserving ID relations. */
+void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root)
+{
+  BKE_main_relations_create(bmain, 0);
+
+  lib_override_library_id_hierarchy_recursive_reset(bmain, id_root);
+
+  BKE_main_relations_free(bmain);
+
+  ID *id;
+  FOREACH_MAIN_ID_BEGIN (bmain, id) {
+    if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) || id->override_library->runtime == NULL ||
+        (id->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD) == 0) {
+      continue;
+    }
+    BKE_lib_override_library_update(bmain, id);
+    id->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD;
+  }
+  FOREACH_MAIN_ID_END;
+}
+
 /** Set or clear given tag in all operations as unused in that override property data. */
 void BKE_lib_override_library_operations_tag(struct IDOverrideLibraryProperty *override_property,
                                              const short tag,



More information about the Bf-blender-cvs mailing list