Fix for [#26712] Particle group instance 'Use Count' value gets reset on file-load.
authorJanne Karhu <jhkarh@gmail.com>
Fri, 15 Jul 2011 13:32:02 +0000 (13:32 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Fri, 15 Jul 2011 13:32:02 +0000 (13:32 +0000)
* New object pointers can't be loaded properly for library linked groups, so the weight groups now store an index to the group objects at save time. This index is used at load time to set the objects without relying on the old pointers.
* If the library linked group is modified the indices can be wrong, but this can't really be avoided easily as there's no way to relate objects in a linked group between loads.

source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/makesdna/DNA_particle_types.h

index 2402106306e9c3bf5ecffcd610c4a110689f66c3..ab30d92f03e7d363e58763a86277578acca55afe 100644 (file)
@@ -75,6 +75,7 @@
 #include "DNA_node_types.h"
 #include "DNA_object_fluidsim.h" // NT
 #include "DNA_packedFile_types.h"
+#include "DNA_particle_types.h"
 #include "DNA_property_types.h"
 #include "DNA_text_types.h"
 #include "DNA_view3d_types.h"
@@ -3161,9 +3162,37 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
                        if(part->effector_weights)
                                part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
 
-                       dw = part->dupliweights.first;
-                       for(; dw; dw=dw->next)
-                               dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+                       if(part->dupliweights.first) {
+                               int index_ok = 0;
+                               /* check for old files without indices (all indexes 0) */
+                               dw = part->dupliweights.first;
+                               if(part->dupliweights.first == part->dupliweights.last) {
+                                       /* special case for only one object in the group */
+                                       index_ok = 1;
+                               }
+                               else { 
+                                       for(; dw; dw=dw->next) {
+                                               if(dw->index > 0) {
+                                                       index_ok = 1;
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               if(index_ok) {
+                                       /* if we have indexes, let's use them */
+                                       dw = part->dupliweights.first;
+                                       for(; dw; dw=dw->next) {
+                                               GroupObject *go = (GroupObject *)BLI_findlink(&part->dup_group->gobject, dw->index);
+                                               dw->ob = go ? go->ob : NULL;
+                                       }
+                               }
+                               else {
+                                       /* otherwise try to get objects from own library (won't work on library linked groups) */
+                                       for(; dw; dw=dw->next)
+                                               dw->ob = newlibadr(fd, part->id.lib, dw->ob);
+                               }
+                       }
 
                        if(part->boids) {
                                BoidState *state = part->boids->states.first;
index ba4395ace9cb6c90cdd1f1c2aa33e8b37f931d90..bf86527b9d337ef9aa6df8ba7c784beb7a4cfb65 100644 (file)
@@ -837,6 +837,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
 {
        ParticleSettings *part;
        ParticleDupliWeight *dw;
+       GroupObject *go;
        int a;
 
        part= idbase->first;
@@ -851,8 +852,16 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
                        writestruct(wd, DATA, "EffectorWeights", 1, part->effector_weights);
 
                        dw = part->dupliweights.first;
-                       for(; dw; dw=dw->next)
+                       for(; dw; dw=dw->next) {
+                               /* update indices */
+                               dw->index = 0;
+                               go = part->dup_group->gobject.first;
+                               while(go && go->ob != dw->ob) {
+                                       go=go->next;
+                                       dw->index++;
+                               }
                                writestruct(wd, DATA, "ParticleDupliWeight", 1, dw);
+                       }
 
                        if(part->boids && part->phystype == PART_PHYS_BOIDS) {
                                BoidState *state = part->boids->states.first;
index aace8156e9d16bc00d2d3fd17524a21569c3e5ef..69ee530c0b65c27dcac5137140069c50c7a74606 100644 (file)
@@ -89,7 +89,8 @@ typedef struct ParticleDupliWeight {
        struct ParticleDupliWeight *next, *prev;
        struct Object *ob;
        short count;
-       short flag, rt[2];
+       short flag;
+       short index, rt; /* only updated on file save and used on file load */
 } ParticleDupliWeight;
 
 typedef struct ParticleData {