LibOverride: Add necessary bits in RNA to deal with embedded IDs paths.
authorBastien Montagne <bastien@blender.org>
Tue, 30 Jun 2020 09:55:11 +0000 (11:55 +0200)
committerBastien Montagne <bastien@blender.org>
Tue, 30 Jun 2020 10:19:11 +0000 (12:19 +0200)
Note that this code is rather rough and slightly hacky, a proper
solution needs to be designed at some point probably, but for now this
should work fine.

As usual, master collections and root node trees remain TODO for now.

source/blender/editors/interface/interface_ops.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access_compare_override.c

index 0894622be4644cc706b6ce9436bf4769cbd032bf..924fc6738e1224818088d2cccd3c9b70dbe15d25 100644 (file)
@@ -630,7 +630,7 @@ static int override_remove_button_exec(bContext *C, wmOperator *op)
   UI_context_active_but_prop_get(C, &ptr, &prop, &index);
 
   ID *id = ptr.owner_id;
-  IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(&ptr, prop);
+  IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(&ptr, prop, &id);
   BLI_assert(oprop != NULL);
   BLI_assert(id != NULL && id->override_library != NULL);
 
index 0b4f82ca263ad2d37ebefa42aed5271e2cf9c6db..53bb8899855f958fe9cd62dad85adbd584b45891 100644 (file)
@@ -1485,7 +1485,8 @@ void RNA_struct_override_apply(struct Main *bmain,
                                struct IDOverrideLibrary *override);
 
 struct IDOverrideLibraryProperty *RNA_property_override_property_find(PointerRNA *ptr,
-                                                                      PropertyRNA *prop);
+                                                                      PropertyRNA *prop,
+                                                                      struct ID **r_owner_id);
 struct IDOverrideLibraryProperty *RNA_property_override_property_get(PointerRNA *ptr,
                                                                      PropertyRNA *prop,
                                                                      bool *r_created);
index f7ce296bbc46a03c85149a33c8276e1fcf66f274..8cd8f80b7c80e0ac98a1bb033627df5f4304f6f7 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "DNA_ID.h"
 #include "DNA_constraint_types.h"
+#include "DNA_key_types.h"
 #include "DNA_modifier_types.h"
 
 #include "BLI_listbase.h"
@@ -1076,18 +1077,70 @@ void RNA_struct_override_apply(Main *bmain,
 #endif
 }
 
-IDOverrideLibraryProperty *RNA_property_override_property_find(PointerRNA *ptr, PropertyRNA *prop)
+static char *rna_property_override_property_real_id_owner(PointerRNA *ptr,
+                                                          PropertyRNA *prop,
+                                                          ID **r_id)
 {
   ID *id = ptr->owner_id;
+  ID *owner_id = id;
+  const char *rna_path_prefix = NULL;
 
-  if (!id || !id->override_library) {
+  *r_id = NULL;
+
+  if (id == NULL) {
+    return NULL;
+  }
+
+  if (id->flag & (LIB_EMBEDDED_DATA | LIB_EMBEDDED_DATA_LIB_OVERRIDE)) {
+    /* XXX this is very bad band-aid code, but for now it will do.
+     * We should at least use a #define for those prop names.
+     * Ideally RNA as a whole should be aware of those PITA of embedded IDs, and have a way to
+     * retrieve their owner IDs and generate paths from those.
+     */
+
+    switch (GS(id->name)) {
+      case ID_KE:
+        owner_id = ((Key *)id)->from;
+        rna_path_prefix = "shape_keys.";
+        break;
+      case ID_GR:
+        /* Master collection, TODO. */
+        break;
+      case ID_NT:
+        /* Root node trees, TODO. */
+        break;
+      default:
+        BLI_assert(0);
+    }
+  }
+
+  if (!ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) {
     return NULL;
   }
 
   char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
   if (rna_path) {
-    IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(id->override_library,
-                                                                           rna_path);
+    char *rna_path_full = rna_path;
+    if (rna_path_prefix != NULL) {
+      rna_path_full = BLI_sprintfN("%s%s", rna_path_prefix, rna_path);
+      MEM_freeN(rna_path);
+    }
+
+    *r_id = owner_id;
+    return rna_path_full;
+  }
+  return NULL;
+}
+
+IDOverrideLibraryProperty *RNA_property_override_property_find(PointerRNA *ptr,
+                                                               PropertyRNA *prop,
+                                                               ID **r_owner_id)
+{
+  char *rna_path;
+
+  if ((rna_path = rna_property_override_property_real_id_owner(ptr, prop, r_owner_id)) != NULL) {
+    IDOverrideLibraryProperty *op = BKE_lib_override_library_property_find(
+        (*r_owner_id)->override_library, rna_path);
     MEM_freeN(rna_path);
     return op;
   }
@@ -1098,14 +1151,10 @@ IDOverrideLibraryProperty *RNA_property_override_property_get(PointerRNA *ptr,
                                                               PropertyRNA *prop,
                                                               bool *r_created)
 {
-  ID *id = ptr->owner_id;
+  ID *id;
+  char *rna_path;
 
-  if (!id || !id->override_library) {
-    return NULL;
-  }
-
-  char *rna_path = RNA_path_from_ID_to_property(ptr, prop);
-  if (rna_path) {
+  if ((rna_path = rna_property_override_property_real_id_owner(ptr, prop, &id)) != NULL) {
     IDOverrideLibraryProperty *op = BKE_lib_override_library_property_get(
         id->override_library, rna_path, r_created);
     MEM_freeN(rna_path);
@@ -1117,7 +1166,8 @@ IDOverrideLibraryProperty *RNA_property_override_property_get(PointerRNA *ptr,
 IDOverrideLibraryPropertyOperation *RNA_property_override_property_operation_find(
     PointerRNA *ptr, PropertyRNA *prop, const int index, const bool strict, bool *r_strict)
 {
-  IDOverrideLibraryProperty *op = RNA_property_override_property_find(ptr, prop);
+  ID *owner_id;
+  IDOverrideLibraryProperty *op = RNA_property_override_property_find(ptr, prop, &owner_id);
 
   if (!op) {
     return NULL;