Bugfix #18725
authorTon Roosendaal <ton@blender.org>
Thu, 14 May 2009 09:32:47 +0000 (09:32 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 14 May 2009 09:32:47 +0000 (09:32 +0000)
Particles using group-duplication, with Metaballs in group, enter eternal
loop in our code now. This is a non-supported case... metaball code doesn't
support recursions. Added a provision in code to catch this case, and print
an error in console to denote this.

source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/scene.c
source/blender/makesdna/DNA_scene_types.h

index 79205814ae7046cca15ae408cfd9b6bdeb6fc73a..97226b5ec42c86300de9a8d2cb316f5f8ac8ea33 100644 (file)
@@ -297,7 +297,10 @@ Object *find_basis_mball(Object *basis)
        splitIDname(basis->id.name+2, basisname, &basisnr);
        totelem= 0;
 
-       next_object(0, 0, 0);
+       /* XXX recursion check, see scene.c, just too simple code this next_object() */
+       if(F_ERROR==next_object(0, 0, 0))
+               return NULL;
+       
        while(next_object(1, &base, &ob)) {
                
                if (ob->type==OB_MBALL) {
index 5def3577218b89ca256f860fcfb84cf987e89008..ed1a77d645e4d7f25eb0db8743745a4093cfaab3 100644 (file)
@@ -402,16 +402,25 @@ int next_object(int val, Base **base, Object **ob)
 {
        static ListBase *duplilist= NULL;
        static DupliObject *dupob;
-       static int fase;
+       static int fase= F_START, in_next_object= 0;
        int run_again=1;
        
        /* init */
        if(val==0) {
                fase= F_START;
                dupob= NULL;
+               
+               /* XXX particle systems with metas+dupligroups call this recursively */
+               /* see bug #18725 */
+               if(in_next_object) {
+                       printf("ERROR: MetaBall generation called recursively, not supported\n");
+                       
+                       return F_ERROR;
+               }
        }
        else {
-
+               in_next_object= 1;
+               
                /* run_again is set when a duplilist has been ended */
                while(run_again) {
                        run_again= 0;
@@ -493,6 +502,9 @@ int next_object(int val, Base **base, Object **ob)
                }
        }
        
+       /* reset recursion test */
+       in_next_object= 0;
+       
        return fase;
 }
 
index d26bdd469f6164a644e59aba231428d2602a00b5..ac73ccc498cb576d5bfbe04f943833051af74ec2 100644 (file)
@@ -788,6 +788,7 @@ typedef struct Scene {
 #define PROP_RANDOM            6
 
        /* return flag next_object function */
+#define F_ERROR                        -1
 #define F_START                        0
 #define F_SCENE                        1
 #define F_SET                  2