LibOverride: add a generic macro to check whetehr an ID is overridable.
authorBastien Montagne <montagne29@wanadoo.fr>
Thu, 5 Sep 2019 18:43:52 +0000 (20:43 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Thu, 5 Sep 2019 19:31:01 +0000 (21:31 +0200)
...and use it in code generating library overrides.

source/blender/editors/interface/interface_templates.c
source/blender/editors/object/object_relations.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/makesdna/DNA_ID.h
source/blender/makesrna/intern/rna_ID.c

index 5a333a5fa27dd9459a915750d29b12fbea502cb2..62eebfdd3c7b8eac57edfa58937de0f844089068 100644 (file)
@@ -516,13 +516,15 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
       if (id) {
         Main *bmain = CTX_data_main(C);
         if (BKE_override_library_is_enabled() && CTX_wm_window(C)->eventstate->shift) {
-          /* Only remap that specific ID usage to overriding local data-block. */
-          ID *override_id = BKE_override_library_create_from_id(bmain, id, false);
-          if (override_id != NULL) {
-            BKE_main_id_clear_newpoins(bmain);
-
-            /* Assign new pointer, takes care of updates/notifiers */
-            RNA_id_pointer_create(override_id, &idptr);
+          if (ID_IS_OVERRIDABLE_LIBRARY(id)) {
+            /* Only remap that specific ID usage to overriding local data-block. */
+            ID *override_id = BKE_override_library_create_from_id(bmain, id, false);
+            if (override_id != NULL) {
+              BKE_main_id_clear_newpoins(bmain);
+
+              /* Assign new pointer, takes care of updates/notifiers */
+              RNA_id_pointer_create(override_id, &idptr);
+            }
           }
         }
         else {
index 60a2b9cca0d265826d64e060ada2bca9b67b9c1a..0d20a07dcee6efdf122eb4b0189ff00bb1df16fe 100644 (file)
@@ -2426,6 +2426,14 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
 
   if (!ID_IS_LINKED(obact) && obact->instance_collection != NULL &&
       ID_IS_LINKED(obact->instance_collection)) {
+    if (!ID_IS_OVERRIDABLE_LIBRARY(obact->instance_collection)) {
+      BKE_reportf(op->reports,
+                  RPT_ERROR_INVALID_INPUT,
+                  "Collection '%s' (instantiated by the active object) is not overridable",
+                  obact->instance_collection->id.name + 2);
+      return OPERATOR_CANCELLED;
+    }
+
     BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
 
     Object *obcollection = obact;
@@ -2507,6 +2515,13 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
     BKE_main_id_clear_newpoins(bmain);
     BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
   }
+  else if (!ID_IS_OVERRIDABLE_LIBRARY(obact)) {
+    BKE_reportf(op->reports,
+                RPT_ERROR_INVALID_INPUT,
+                "Active object '%s' is not overridable",
+                obact->id.name + 2);
+    return OPERATOR_CANCELLED;
+  }
   /* Else, poll func ensures us that ID_IS_LINKED(obact) is true. */
   else if (obact->type == OB_ARMATURE) {
     BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
index 91d7f0f9374962c367de0d73c4ff2b1a61a78dd0..219943d08a6cf73b3c17baef2912eb636f0f8697 100644 (file)
@@ -713,7 +713,7 @@ static void id_override_library_cb(bContext *C,
                                    TreeStoreElem *tselem,
                                    void *UNUSED(user_data))
 {
-  if (ID_IS_LINKED(tselem->id) && (tselem->id->tag & LIB_TAG_EXTERN)) {
+  if (ID_IS_OVERRIDABLE_LIBRARY(tselem->id)) {
     Main *bmain = CTX_data_main(C);
     /* For now, remapp all local usages of linked ID to local override one here. */
     BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, true);
index ed7416e06c90c1a9d9915fb2da925b484f8571b5..a1bc71ade62b5dccbef84cc468eab942b9236884 100644 (file)
@@ -432,10 +432,15 @@ typedef enum ID_Type {
 #define ID_BLEND_PATH_FROM_GLOBAL(_id) \
   ((_id)->lib ? (_id)->lib->filepath : BKE_main_blendfile_path_from_global())
 
-#define ID_MISSING(_id) (((_id)->tag & LIB_TAG_MISSING) != 0)
+#define ID_MISSING(_id) ((((ID *)(_id))->tag & LIB_TAG_MISSING) != 0)
 
 #define ID_IS_LINKED(_id) (((ID *)(_id))->lib != NULL)
 
+/* Note that this is a fairly high-level check, should be used at user interaction level, not in
+ * BKE_library_override typically (especially due to the check on LIB_TAG_EXTERN). */
+#define ID_IS_OVERRIDABLE_LIBRARY(_id) \
+  (ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((ID *)(_id))->tag & LIB_TAG_EXTERN) != 0)
+
 #define ID_IS_OVERRIDE_LIBRARY(_id) \
   (((ID *)(_id))->override_library != NULL && ((ID *)(_id))->override_library->reference != NULL)
 
index 294fdb2e0d8c624e2e9bc6b11b406a00f0f2c6ef..49fdf9c67d5504ac652c579da2fbd8957f6ad0a5 100644 (file)
@@ -493,7 +493,7 @@ static ID *rna_ID_copy(ID *id, Main *bmain)
 
 static ID *rna_ID_override_create(ID *id, Main *bmain, bool remap_local_usages)
 {
-  if (!BKE_override_library_is_enabled() || id->lib == NULL) {
+  if (!BKE_override_library_is_enabled() || !ID_IS_OVERRIDABLE_LIBRARY(id)) {
     return NULL;
   }