Commit: aeaf2b0dd437f1a03ed30142678cbf44d0414ea1
Author: Bastien Montagne
Date:   Wed Aug 19 16:24:58 2020 +0200
Branches: master
https://developer.blender.org/rBaeaf2b0dd437f1a03ed30142678cbf44d0414ea1

LibOverride: Add initial version of 'resync' operation.

Available from the usual ID submenu in the Outliner context menu.

The goal of this operator is to re-create the override from the linked
data, while preserving existing defined overrides.

This allows to update local opverrides when relations between datablocks
are changed in source library linked data.

Part of T76555.

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

M       source/blender/blenkernel/BKE_lib_override.h
M       source/blender/blenkernel/intern/lib_override.c
M       source/blender/editors/space_outliner/outliner_tools.c

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

diff --git a/source/blender/blenkernel/BKE_lib_override.h 
b/source/blender/blenkernel/BKE_lib_override.h
index 5843992b25c..7b10ed4d43c 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -68,11 +68,19 @@ void BKE_lib_override_library_dependencies_tag(struct Main 
*bmain,
                                                struct ID *id_root,
                                                const uint tag,
                                                const bool 
do_create_main_relashionships);
+void BKE_lib_override_library_override_group_tag(struct Main *bmain,
+                                                 struct ID *id_root,
+                                                 const uint tag,
+                                                 const bool 
do_create_main_relashionships);
 bool BKE_lib_override_library_create(struct Main *bmain,
                                      struct Scene *scene,
                                      struct ViewLayer *view_layer,
                                      struct ID *id_root,
                                      struct ID *id_reference);
+bool BKE_lib_override_library_resync(struct Main *bmain,
+                                     struct Scene *scene,
+                                     struct ViewLayer *view_layer,
+                                     struct ID *id_root);
 
 struct IDOverrideLibraryProperty *BKE_lib_override_library_property_find(
     struct IDOverrideLibrary *override, const char *rna_path);
diff --git a/source/blender/blenkernel/intern/lib_override.c 
b/source/blender/blenkernel/intern/lib_override.c
index 5b45148ed63..6b808d8132c 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -361,7 +361,10 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
   return success;
 }
 
-static bool lib_override_hierarchy_recursive_tag(Main *bmain, ID *id, const 
uint tag)
+static bool lib_override_hierarchy_recursive_tag(Main *bmain,
+                                                 ID *id,
+                                                 const uint tag,
+                                                 Library 
*override_group_lib_reference)
 {
   void **entry_vp = BLI_ghash_lookup_p(bmain->relations->id_user_to_used, id);
   if (entry_vp == NULL) {
@@ -369,6 +372,11 @@ static bool lib_override_hierarchy_recursive_tag(Main 
*bmain, ID *id, const uint
     return (id->tag & tag) != 0;
   }
 
+  if (override_group_lib_reference != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(id) 
&&
+      id->override_library->reference->lib == override_group_lib_reference) {
+    id->tag |= tag;
+  }
+
   /* 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.
@@ -383,7 +391,9 @@ static bool lib_override_hierarchy_recursive_tag(Main 
*bmain, ID *id, const uint
     }
     /* We only consider IDs from the same library. */
     if (entry->id_pointer != NULL && (*entry->id_pointer)->lib == id->lib) {
-      if (lib_override_hierarchy_recursive_tag(bmain, *entry->id_pointer, 
tag)) {
+      if (lib_override_hierarchy_recursive_tag(
+              bmain, *entry->id_pointer, tag, override_group_lib_reference) &&
+          override_group_lib_reference == NULL) {
         id->tag |= tag;
       }
     }
@@ -395,6 +405,7 @@ static bool lib_override_hierarchy_recursive_tag(Main 
*bmain, ID *id, const uint
 /**
  * Tag all IDs in given \a bmain that are being used by given \a id_root ID or 
its dependencies,
  * recursively.
+ * It detects and tag only chains of dependencies marked at both ends by given 
tag.
  *
  * This will include all local IDs, and all IDs from the same library as the 
\a id_root.
  *
@@ -402,8 +413,8 @@ static bool lib_override_hierarchy_recursive_tag(Main 
*bmain, ID *id, const uint
  * \param do_create_main_relashionships Whether main relations needs to be 
created or already exist
  *                                      (in any case, they will be freed by 
this function).
  */
-void BKE_lib_override_library_dependencies_tag(struct Main *bmain,
-                                               struct ID *id_root,
+void BKE_lib_override_library_dependencies_tag(Main *bmain,
+                                               ID *id_root,
                                                const uint tag,
                                                const bool 
do_create_main_relashionships)
 {
@@ -411,10 +422,35 @@ void BKE_lib_override_library_dependencies_tag(struct 
Main *bmain,
     BKE_main_relations_create(bmain, 0);
   }
 
-  /* Then we tag all intermediary data-blocks in-between two overridden ones 
(e.g. if a shapekey
+  /* We tag all intermediary data-blocks in-between two overridden ones (e.g. 
if a shapekey
    * has a driver using an armature object's bone, we need to override the 
shapekey/obdata, the
    * objects using them, etc.) */
-  lib_override_hierarchy_recursive_tag(bmain, id_root, tag);
+  lib_override_hierarchy_recursive_tag(bmain, id_root, tag, NULL);
+
+  BKE_main_relations_free(bmain);
+}
+
+/**
+ * Tag all IDs in given \a bmain that are part of the same \a id_root 
liboverride ID group.
+ * That is, all other liboverrides IDs (in)directly used by \a is_root one, 
sharing the same
+ * library for their reference IDs.
+ *
+ * \param id_root The root of the hierarchy of liboverride dependencies to be 
tagged.
+ * \param do_create_main_relashionships Whether main relations needs to be 
created or already exist
+ *                                      (in any case, they will be freed by 
this function).
+ */
+void BKE_lib_override_library_override_group_tag(Main *bmain,
+                                                 ID *id_root,
+                                                 const uint tag,
+                                                 const bool 
do_create_main_relashionships)
+{
+  if (do_create_main_relashionships) {
+    BKE_main_relations_create(bmain, 0);
+  }
+
+  /* We tag all liboverride data-blocks from the same library as reference 
one, being used by the root ID. */
+  lib_override_hierarchy_recursive_tag(
+      bmain, id_root, tag, id_root->override_library->reference->lib);
 
   BKE_main_relations_free(bmain);
 }
@@ -459,26 +495,7 @@ static int 
lib_override_library_make_tag_ids_cb(LibraryIDLinkCallbackData *cb_da
   return IDWALK_RET_NOP;
 }
 
-/**
- * Advanced 'smart' function to create fully functional overrides.
- *
- * \note Currently it only does special things if given \a id_root is an 
object of collection, more
- * specific behaviors may be added in the future for other ID types.
- *
- * \note It will overrides all IDs tagged with \a LIB_TAG_DOIT, and it does 
not clear that tag at
- * its beginning, so caller code can add extra data-blocks to be overridden as 
well.
- *
- * \note In the future that same function may be extended to support 'refresh' 
of overrides
- * (rebuilding overrides from linked data, trying to preserve local overrides 
already defined).
- *
- * \param id_root The root ID to create an override from.
- * \param id_reference some reference ID used to do some post-processing after 
overrides have been
- *                     created, may be NULL. Typically, the Empty object 
instantiating the linked
- *                     collection we override, currently.
- * \return true if override was successfully created.
- */
-bool BKE_lib_override_library_create(
-    Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, ID 
*id_reference)
+static bool lib_override_library_create_do(Main *bmain, ID *id_root)
 {
   /* Tag all collections and objects, as well as other IDs using them. */
   id_root->tag |= LIB_TAG_DOIT;
@@ -508,109 +525,258 @@ bool BKE_lib_override_library_create(
   /* Note that this call will also free the main relations data we created 
above. */
   BKE_lib_override_library_dependencies_tag(bmain, id_root, LIB_TAG_DOIT, 
false);
 
-  const bool success = BKE_lib_override_library_create_from_tag(bmain);
-
-  if (success) {
-    BKE_main_collection_sync(bmain);
-
-    switch (GS(id_root->name)) {
-      case ID_GR: {
-        Object *ob_reference = id_reference != NULL && GS(id_reference->name) 
== ID_OB ?
-                                   (Object *)id_reference :
-                                   NULL;
-        Collection *collection_new = ((Collection *)id_root->newid);
-        if (ob_reference != NULL) {
-          BKE_collection_add_from_object(bmain, scene, ob_reference, 
collection_new);
-        }
-        else {
-          BKE_collection_add_from_collection(
-              bmain, scene, ((Collection *)id_root), collection_new);
-        }
+  return BKE_lib_override_library_create_from_tag(bmain);
+}
 
-        FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection_new, ob_new) {
-          if (ob_new != NULL && ob_new->id.override_library != NULL) {
-            if (ob_reference != NULL) {
-              Base *base;
-              if ((base = BKE_view_layer_base_find(view_layer, ob_new)) == 
NULL) {
-                BKE_collection_object_add_from(bmain, scene, ob_reference, 
ob_new);
-                base = BKE_view_layer_base_find(view_layer, ob_new);
-                DEG_id_tag_update_ex(
-                    bmain, &ob_new->id, ID_RECALC_TRANSFORM | 
ID_RECALC_BASE_FLAGS);
-              }
+static void lib_override_library_create_post_process(
+    Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, ID 
*id_reference)
+{
+  BKE_main_collection_sync(bmain);
+
+  switch (GS(id_root->name)) {
+    case ID_GR: {
+      Object *ob_reference = id_reference != NULL && GS(id_reference->name) == 
ID_OB ?
+                                 (Object *)id_reference :
+                                 NULL;
+      Collection *collection_new = ((Collection *)id_root->newid);
+      if (ob_reference != NULL) {
+        BKE_collection_add_from_object(bmain, scene, ob_reference, 
collection_new);
+      }
+      else {
+        BKE_collection_add_from_collection(bmain, scene, ((Collection 
*)id_root), collection_new);
+      }
 
-              if (ob_new == (Object

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to