Re-establish link to proxies when they are made local after appending.
authorSybren A. Stüvel <sybren@stuvel.eu>
Thu, 6 Oct 2016 14:52:13 +0000 (16:52 +0200)
committerSybren A. Stüvel <sybren@stuvel.eu>
Fri, 7 Oct 2016 11:08:50 +0000 (13:08 +0200)
This allows appending of an entire scene from another blend file into
this one, even when that blend file contains proxified armatures.

Since the proxified object needs to be linked (not local), this will
only work when the "Localize all" checkbox is disabled. The appended
proxy object should also not be referenced from anything in a library
(for example in a constraint). Referencing it from the appended data
should be fine.

Fixes T49495.

source/blender/blenkernel/intern/library.c

index 6d94cd28b31b04ba967dcd7a85a1b0bcdd80e887..2d444a610e5caed191f2165916c0cd876e53fdb6 100644 (file)
@@ -1715,6 +1715,36 @@ void BKE_library_make_local(Main *bmain, const Library *lib, const bool untagged
                                        bool is_local = false, is_lib = false;
 
                                        BKE_library_ID_test_usages(bmain, id, &is_local, &is_lib);
+
+                                       /* Attempt to re-link appended proxy objects. This allows appending of an entire scene
+                                        * from another blend file into this one, even when that blend file contains proxified
+                                        * armatures. Since the proxified object needs to be linked (not local), this will
+                                        * only work when the "Localize all" checkbox is disabled.
+                                        * TL;DR: this is a dirty hack on top of an already weak feature (proxies). */
+                                       if (GS(id->name) == ID_OB && ((Object *)id)->proxy != NULL) {
+                                               Object *ob = (Object *)id;
+                                               Object *ob_new = (Object *)id->newid;
+
+                                               /* Proxies only work when the proxied object is linked-in from a library. */
+                                               if (ob->proxy->id.lib == NULL) {
+                                                       printf("Warning, proxy object %s will loose its link to %s, because the "
+                                                              "proxied object is local.\n", id->newid->name, ob->proxy->id.name);
+                                               }
+                                               /* We can only switch the proxy'ing to a made-local proxy if it is no longer
+                                                * referred to from a library. Not checking for local use; if new local proxy
+                                                * was not used locally would be a nasty bug! */
+                                               else if (is_local || is_lib) {
+                                                       printf("Warning, made-local proxy object %s will loose its link to %s, "
+                                                              "because the linked-in proxy is referenced (is_local=%i, is_lib=%i).\n",
+                                                              id->newid->name, ob->proxy->id.name, is_local, is_lib);
+                                               }
+                                               else {
+                                                       /* we can switch the proxy'ing from the linked-in to the made-local proxy. */
+                                                       BKE_object_make_proxy(ob_new, ob->proxy, ob->proxy_group);
+                                                       ob->proxy = ob->proxy_from = ob->proxy_group = NULL;
+                                               }
+                                       }
+
                                        if (!is_local && !is_lib) {
                                                BKE_libblock_free(bmain, id);
                                                do_loop = true;