[Bf-blender-cvs] [8de1a6d6456] override-refactor-tmp-2: LibOverride: First stage of detection of 'need resync'.

Bastien Montagne noreply at git.blender.org
Fri Mar 5 10:14:18 CET 2021


Commit: 8de1a6d6456c8c7307e8511564995efcc34b017f
Author: Bastien Montagne
Date:   Thu Dec 31 18:03:45 2020 +0100
Branches: override-refactor-tmp-2
https://developer.blender.org/rB8de1a6d6456c8c7307e8511564995efcc34b017f

LibOverride: First stage of detection of 'need resync'.

We can fairly easily detect some resync-needed cases when applying the
overrides operations on a Pointer RNA property.

This should cover all cases where an existing override's ID pointer is
changed in its linked data.

We still have to add code to detect when a not-yet-overridden linked ID
needs to become overridden (because its relations to other data-blocks
changed in a way that requires it).

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

M	source/blender/blenkernel/intern/lib_override.c
M	source/blender/makesdna/DNA_ID.h
M	source/blender/makesrna/intern/rna_access_compare_override.c
M	source/blender/makesrna/intern/rna_rna.c

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

diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index c8add0245b5..c687a49d704 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -905,6 +905,8 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
         ID *id_override_new = id->newid;
         ID *id_override_old = BLI_ghash_lookup(linkedref_to_old_override, id);
 
+        BLI_assert((id_override_new->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0);
+
         if (id_override_old != NULL) {
           /* Swap the names between old override ID and new one. */
           char id_name_buf[MAX_ID_NAME];
@@ -1918,6 +1920,14 @@ void BKE_lib_override_library_main_unused_cleanup(struct Main *bmain)
   FOREACH_MAIN_ID_END;
 }
 
+static void lib_override_id_swap(Main *bmain, ID *id_local, ID *id_temp)
+{
+  BKE_lib_id_swap(bmain, id_local, id_temp);
+  /* We need to keep these tags from temp ID into orig one.
+   * ID swap does not swap most of ID data itself. */
+  id_local->tag |= (id_temp->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC);
+}
+
 /** Update given override from its reference (re-applying overridden properties). */
 void BKE_lib_override_library_update(Main *bmain, ID *local)
 {
@@ -1986,11 +1996,11 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
 
   /* This also transfers all pointers (memory) owned by local to tmp_id, and vice-versa.
    * So when we'll free tmp_id, we'll actually free old, outdated data from local. */
-  BKE_lib_id_swap(bmain, local, tmp_id);
+  lib_override_id_swap(bmain, local, tmp_id);
 
   if (local_key != NULL && tmp_key != NULL) {
     /* This is some kind of hard-coded 'always enforced override'. */
-    BKE_lib_id_swap(bmain, &local_key->id, &tmp_key->id);
+    lib_override_id_swap(bmain, &local_key->id, &tmp_key->id);
     tmp_key->id.flag |= (local_key->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE);
     /* The swap of local and tmp_id inverted those pointers, we need to redefine proper
      * relationships. */
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 14f0fef5270..55cb600779f 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -566,6 +566,11 @@ enum {
   /* RESET_AFTER_USE Used by undo system to tag unchanged IDs re-used from old Main (instead of
    * read from memfile). */
   LIB_TAG_UNDO_OLD_ID_REUSED = 1 << 19,
+
+  /**
+   * The data-block is a library override that needs re-sync to its linked reference.
+   */
+  LIB_TAG_LIB_OVERRIDE_NEED_RESYNC = 1 << 13,
 };
 
 /* Tag given ID for an update in all the dependency graphs. */
diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c
index d6305388cf9..a8b701875b7 100644
--- a/source/blender/makesrna/intern/rna_access_compare_override.c
+++ b/source/blender/makesrna/intern/rna_access_compare_override.c
@@ -57,7 +57,7 @@
  * Find the actual ID owner of the given \a ptr #PointerRNA, in override sense, and generate the
  * full rna path from it to given \a prop #PropertyRNA if \a rna_path is given.
  *
- * \note this is slightly different than 'generic' RNA 'id owner' as returned by
+ * \note This is slightly different than 'generic' RNA 'id owner' as returned by
  * #RNA_find_real_ID_and_path, since in overrides we also consider shape keys as embedded data, not
  * only root node trees and master collections.
  */
@@ -100,10 +100,6 @@ static ID *rna_property_override_property_real_id_owner(Main *bmain,
     }
   }
 
-  if (!ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
-    return NULL;
-  }
-
   if (r_rna_path == NULL) {
     return owner_id;
   }
@@ -1153,6 +1149,38 @@ void RNA_struct_override_apply(Main *bmain,
               ptr_storage, op->rna_path, &data_storage, &prop_storage, &data_item_storage);
         }
 
+        /* Check if an overridden ID pointer supposed to be in sync with linked data gets out of
+         * sync. */
+        if ((ptr_dst->owner_id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0 &&
+            op->rna_prop_type == PROP_POINTER &&
+            (((IDOverrideLibraryPropertyOperation *)op->operations.first)->flag &
+             IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) != 0) {
+          BLI_assert(ptr_src->owner_id ==
+                     rna_property_override_property_real_id_owner(bmain, &data_src, NULL, NULL));
+          BLI_assert(ptr_dst->owner_id ==
+                     rna_property_override_property_real_id_owner(bmain, &data_dst, NULL, NULL));
+
+          PointerRNA prop_ptr_src = RNA_property_pointer_get(&data_src, prop_src);
+          PointerRNA prop_ptr_dst = RNA_property_pointer_get(&data_dst, prop_dst);
+          ID *id_src = rna_property_override_property_real_id_owner(
+              bmain, &prop_ptr_src, NULL, NULL);
+          ID *id_dst = rna_property_override_property_real_id_owner(
+              bmain, &prop_ptr_dst, NULL, NULL);
+
+          BLI_assert(id_src == NULL || ID_IS_OVERRIDE_LIBRARY_REAL(id_src));
+
+          if (/* We might be in a case where id_dst has already been processed and its usages
+               * remapped to its new local override. In that case overrides and linked data are
+               * always properly matching. */
+              id_src != id_dst &&
+              /* If one of the pointers is NULL and not the other, or if linked reference ID of
+               * `id_src` is not `id_dst`,  we are in a non-matching case. */
+              (ELEM(NULL, id_src, id_dst) || id_src->override_library->reference != id_dst)) {
+            ptr_dst->owner_id->tag |= LIB_TAG_LIB_OVERRIDE_NEED_RESYNC;
+            printf("Local override %s detected as needing resync!\n", ptr_dst->owner_id->name);
+          }
+        }
+
         rna_property_override_apply_ex(bmain,
                                        &data_dst,
                                        &data_src,
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index b0a942cd39e..32f7f239431 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -1238,6 +1238,8 @@ static bool rna_property_override_diff_propptr_validate_diffing(PointerRNA *prop
 
 /* Used for both Pointer and Collection properties. */
 static int rna_property_override_diff_propptr(Main *bmain,
+                                              ID *owner_id_a,
+                                              ID *owner_id_b,
                                               PointerRNA *propptr_a,
                                               PointerRNA *propptr_b,
                                               eRNACompareMode mode,
@@ -1359,6 +1361,17 @@ static int rna_property_override_diff_propptr(Main *bmain,
                * override is not matching its reference anymore. */
               opop->flag &= ~IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE;
             }
+            else if ((owner_id_a->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) != 0 ||
+                     (owner_id_b->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) != 0) {
+              /* In case one of the owner of the checked property is tagged as needing resync, do
+               * not change the 'match reference' status of its ID pointer properties overrides,
+               * since many non-matching ones are likely due to missing resync. */
+              printf(
+                  "%s: Not checking matching ID pointer properties, since owner %s is tagged as "
+                  "needing resync.\n",
+                  __func__,
+                  id_a->name);
+            }
             else if (id_a->override_library != NULL && id_a->override_library->reference == id_b) {
               opop->flag |= IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE;
             }
@@ -1778,6 +1791,8 @@ int rna_property_override_diff_default(Main *bmain,
         PointerRNA propptr_a = RNA_property_pointer_get(ptr_a, rawprop_a);
         PointerRNA propptr_b = RNA_property_pointer_get(ptr_b, rawprop_b);
         return rna_property_override_diff_propptr(bmain,
+                                                  ptr_a->owner_id,
+                                                  ptr_b->owner_id,
                                                   &propptr_a,
                                                   &propptr_b,
                                                   mode,
@@ -1934,6 +1949,8 @@ int rna_property_override_diff_default(Main *bmain,
           else if (is_id || is_valid_for_diffing) {
             if (equals || do_create) {
               const int eq = rna_property_override_diff_propptr(bmain,
+                                                                ptr_a->owner_id,
+                                                                ptr_b->owner_id,
                                                                 &iter_a.ptr,
                                                                 &iter_b.ptr,
                                                                 mode,



More information about the Bf-blender-cvs mailing list