[Bf-blender-cvs] [a94a05ec19c] master: LibOverride: Add proper handling of shapekeys to core override code itself.

Bastien Montagne noreply at git.blender.org
Tue Jun 30 12:19:18 CEST 2020


Commit: a94a05ec19cbb8f7e09f55f736d3a82665a357ae
Author: Bastien Montagne
Date:   Tue Jun 30 12:02:38 2020 +0200
Branches: master
https://developer.blender.org/rBa94a05ec19cbb8f7e09f55f736d3a82665a357ae

LibOverride: Add proper handling of shapekeys to core override code itself.

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

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

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

diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 4be0c7ce16f..46eb40e0315 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -27,12 +27,15 @@
 #include "MEM_guardedalloc.h"
 
 #include "DNA_ID.h"
+#include "DNA_key_types.h"
 #include "DNA_object_types.h"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_build.h"
 
 #include "BKE_armature.h"
+#include "BKE_idtype.h"
+#include "BKE_key.h"
 #include "BKE_lib_id.h"
 #include "BKE_lib_override.h"
 #include "BKE_lib_remap.h"
@@ -201,6 +204,16 @@ static ID *lib_override_library_create_from(Main *bmain, ID *reference_id)
 
   BKE_lib_override_library_init(local_id, reference_id);
 
+  /* Note: From liboverride perspective (and RNA one), shape keys are considered as local embedded
+   * data-blocks, just like root node trees or master collections. Therefore, we never need to
+   * create overrides for them. We need a way to mark them as overrides though. */
+  Key *reference_key;
+  if ((reference_key = BKE_key_from_id(reference_id)) != NULL) {
+    Key *local_key = BKE_key_from_id(local_id);
+    BLI_assert(local_key != NULL);
+    local_key->id.flag |= LIB_EMBEDDED_DATA_LIB_OVERRIDE;
+  }
+
   return local_id;
 }
 
@@ -215,6 +228,12 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain,
   ID *local_id = lib_override_library_create_from(bmain, reference_id);
 
   if (do_tagged_remap) {
+    Key *reference_key, *local_key = NULL;
+    if ((reference_key = BKE_key_from_id(reference_id)) != NULL) {
+      local_key = BKE_key_from_id(local_id);
+      BLI_assert(local_key != NULL);
+    }
+
     ID *other_id;
     FOREACH_MAIN_ID_BEGIN (bmain, other_id) {
       if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib == NULL) {
@@ -225,6 +244,13 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain,
                                reference_id,
                                local_id,
                                ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+        if (reference_key != NULL) {
+          BKE_libblock_relink_ex(bmain,
+                                 other_id,
+                                 &reference_key->id,
+                                 &local_key->id,
+                                 ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+        }
       }
     }
     FOREACH_MAIN_ID_END;
@@ -256,7 +282,8 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
 
   /* Get all IDs we want to override. */
   FOREACH_MAIN_ID_BEGIN (bmain, reference_id) {
-    if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL) {
+    if ((reference_id->tag & LIB_TAG_DOIT) != 0 && reference_id->lib != NULL &&
+        BKE_idtype_idcode_is_linkable(GS(reference_id->name))) {
       todo_id_iter = MEM_callocN(sizeof(*todo_id_iter), __func__);
       todo_id_iter->data = reference_id;
       BLI_addtail(&todo_ids, todo_id_iter);
@@ -269,38 +296,71 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain)
     reference_id = todo_id_iter->data;
     if ((reference_id->newid = lib_override_library_create_from(bmain, reference_id)) == NULL) {
       success = false;
+      break;
     }
-    else {
+    /* We also tag the new IDs so that in next step we can remap their pointers too. */
+    reference_id->newid->tag |= LIB_TAG_DOIT;
+
+    Key *reference_key;
+    if ((reference_key = BKE_key_from_id(reference_id)) != NULL) {
+      reference_key->id.tag |= LIB_TAG_DOIT;
+
+      Key *local_key = BKE_key_from_id(reference_id->newid);
+      BLI_assert(local_key != NULL);
+      reference_key->id.newid = &local_key->id;
       /* We also tag the new IDs so that in next step we can remap their pointers too. */
-      reference_id->newid->tag |= LIB_TAG_DOIT;
+      local_key->id.tag |= LIB_TAG_DOIT;
     }
   }
 
   /* Only remap new local ID's pointers, we don't want to force our new overrides onto our whole
    * existing linked IDs usages. */
-  for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) {
-    ID *other_id;
-    reference_id = todo_id_iter->data;
+  if (success) {
+    for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) {
+      ID *other_id;
+      reference_id = todo_id_iter->data;
+      ID *local_id = reference_id->newid;
+
+      if (local_id == NULL) {
+        continue;
+      }
 
-    if (reference_id->newid == NULL) {
-      continue;
-    }
+      Key *reference_key, *local_key = NULL;
+      if ((reference_key = BKE_key_from_id(reference_id)) != NULL) {
+        local_key = BKE_key_from_id(reference_id->newid);
+        BLI_assert(local_key != NULL);
+      }
 
-    /* Still checking the whole Main, that way we can tag other local IDs as needing to be remapped
-     * to use newly created overriding IDs, if needed. */
-    FOREACH_MAIN_ID_BEGIN (bmain, other_id) {
-      if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib == NULL) {
-        ID *local_id = reference_id->newid;
-        /* Note that using ID_REMAP_SKIP_INDIRECT_USAGE below is superfluous, as we only remap
-         * local IDs usages anyway... */
-        BKE_libblock_relink_ex(bmain,
-                               other_id,
-                               reference_id,
-                               local_id,
-                               ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+      /* Still checking the whole Main, that way we can tag other local IDs as needing to be
+       * remapped to use newly created overriding IDs, if needed. */
+      FOREACH_MAIN_ID_BEGIN (bmain, other_id) {
+        if ((other_id->tag & LIB_TAG_DOIT) != 0 && other_id->lib == NULL) {
+          /* Note that using ID_REMAP_SKIP_INDIRECT_USAGE below is superfluous, as we only remap
+           * local IDs usages anyway... */
+          BKE_libblock_relink_ex(bmain,
+                                 other_id,
+                                 reference_id,
+                                 local_id,
+                                 ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+          if (reference_key != NULL) {
+            BKE_libblock_relink_ex(bmain,
+                                   other_id,
+                                   &reference_key->id,
+                                   &local_key->id,
+                                   ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_OVERRIDE_LIBRARY);
+          }
+        }
       }
+      FOREACH_MAIN_ID_END;
+    }
+  }
+  else {
+    /* We need to cleanup potentially already created data. */
+    for (todo_id_iter = todo_ids.first; todo_id_iter != NULL; todo_id_iter = todo_id_iter->next) {
+      reference_id = todo_id_iter->data;
+      BKE_id_delete(bmain, reference_id->newid);
+      reference_id->newid = NULL;
     }
-    FOREACH_MAIN_ID_END;
   }
 
   BLI_freelistN(&todo_ids);
@@ -975,6 +1035,16 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
    * manual handling here. */
   BLI_strncpy(tmp_id->name, local->name, sizeof(tmp_id->name));
 
+  /* Those ugly loopback pointers again... Luckily we only need to deal with the shape keys here,
+   * collections' parents are fully runtime and reconstructed later. */
+  Key *local_key = BKE_key_from_id(local);
+  Key *tmp_key = BKE_key_from_id(tmp_id);
+  if (local_key != NULL && tmp_key != NULL) {
+    /* This is some kind of hard-coded 'always enforced override'... */
+    tmp_key->from = local_key->from;
+    tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
+  }
+
   PointerRNA rnaptr_src, rnaptr_dst, rnaptr_storage_stack, *rnaptr_storage = NULL;
   RNA_id_pointer_create(local, &rnaptr_src);
   RNA_id_pointer_create(tmp_id, &rnaptr_dst);



More information about the Bf-blender-cvs mailing list