Fix for two proxy + undo related crashes:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 2 Nov 2008 00:25:39 +0000 (00:25 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 2 Nov 2008 00:25:39 +0000 (00:25 +0000)
* When making a proxy, the lib linked IPO driver was also changed to
  point to the proxy object, and after undo this local proxy object
  was replaced so the pointer became invalid. In fact it is not needed
  at all to change this because the IPO code maps the pointer to the
  local proxy object already.
* Undoing the make proxy operation would crash because the proxy_from
  pointer in the library linked object would still point to the removed
  object. Now it clears all these pointers before undo, because on each
  undo memory file read they will be set again anyway.

source/blender/blenkernel/intern/object.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h

index 77c891ee82eb0bcabae44ac7c0240eb82d15effe..a25afeafaef5fb3edd115b3ff865439c82d6cecb 100644 (file)
@@ -1163,7 +1163,10 @@ static void copy_object_pose(Object *obn, Object *ob)
                        ListBase targets = {NULL, NULL};
                        bConstraintTarget *ct;
                        
-                       if(con->ipo) {
+                       /* note that we can't change lib linked ipo blocks. for making
+                        * proxies this still works correct however because the object
+                        * is changed to object->proxy_from when evaluating the driver. */
+                       if(con->ipo && !con->ipo->id.lib) {
                                IpoCurve *icu;
                                for(icu= con->ipo->curve.first; icu; icu= icu->next) {
                                        if(icu->driver && icu->driver->ob==ob)
index 5a75b5c8b110426dd5dcaac269dde28a6d1c51c3..e4bc6e3abb208b8e07ce0a82dee5bbbccc0ebaac 100644 (file)
@@ -364,6 +364,9 @@ BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, Ble
        if (fd) {
                strcpy(fd->filename, filename);
                
+               /* clear ob->proxy_from pointers in G.main */
+               blo_clear_proxy_pointers_from_lib(fd);
+
                /* separate libraries from G.main */
                blo_split_main(&mainlist, G.main);
                /* add the library pointers in oldmap lookup */
index 3a9d0a6ae6a16cd611658fe33c86cf2886cb4df8..acedf51e6191f050d02e7e8c67f3d8bd12766661 100644 (file)
@@ -1130,6 +1130,19 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi
        }
 }
 
+/* lib linked proxy objects point to our local data, we need
+ * to clear that pointer before reading the undo memfile since
+ * the object might be removed, it is set again in reading
+ * if the local object still exists */
+void blo_clear_proxy_pointers_from_lib(FileData *fd)
+{
+       Object *ob= G.main->object.first;
+       
+       for(;ob; ob= ob->id.next)
+               if(ob->id.lib)
+                       ob->proxy_from= NULL;
+}
+
 /* assumed; G.main still exists */
 void blo_make_image_pointer_map(FileData *fd)
 {
index 7ddb1e361da010cfde4ccaad36a356bae60ae9c9..8547a4d96523b6c6d82a230642ab15339bba514e 100644 (file)
@@ -112,6 +112,7 @@ FileData *blo_openblenderfile( char *name, BlendReadError *error_r);
 FileData *blo_openblendermemory( void *buffer, int buffersize, BlendReadError *error_r);
 FileData *blo_openblendermemfile(struct MemFile *memfile, BlendReadError *error_r);
 
+void blo_clear_proxy_pointers_from_lib(FileData *fd);
 void blo_make_image_pointer_map(FileData *fd);
 void blo_end_image_pointer_map(FileData *fd);
 void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd);