Fixed preconditioned conjugate to some degree but some issues left for stiffness...
authorDaniel Genrich <daniel.genrich@gmx.net>
Wed, 12 Dec 2007 17:33:59 +0000 (17:33 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Wed, 12 Dec 2007 17:33:59 +0000 (17:33 +0000)
16 files changed:
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/makesdna/DNA_key_types.h
source/blender/nodes/intern/CMP_nodes/CMP_normalize.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/drawview.c
source/blender/src/editkey.c
source/blender/src/editmesh_mods.c
source/blender/src/editparticle.c

index c8ec1698b86d899547e992dd17090fe0cd86cec5..e288e7ee082689d5acf52be16928e47a993849b4 100644 (file)
@@ -200,7 +200,6 @@ typedef void ( *CM_COLLISION_SELF ) ( struct ClothModifierData *clmd, int step )
 // only one available in the moment
 typedef enum {
     CM_IMPLICIT = 0,
-    CM_VERLET = 1,
 } CM_SOLVER_ID;
 
 
index 020b9d15417a3f9a2cd4b457e8872eb0ef119985..afaf9dbeee2e6d6f17da41754e75cec5c1ecf9bf 100644 (file)
@@ -44,5 +44,6 @@
 int    BKE_ptcache_id_filename(struct ID *id, char *filename, int cfra, int stack_index, short do_path, short do_ext);
 FILE * BKE_ptcache_id_fopen(struct ID *id, char mode, int cfra, int stack_index);
 void   BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index);
+int            BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index);
 
 #endif
index c83e9f7fbe13574d8c0bbad59740b84b397bc7ec..355cd19da3358a155dc66fdd1336c6fa23e51bac 100644 (file)
@@ -7,7 +7,7 @@ incs = '. #/intern/guardedalloc ../include ../blenlib ../makesdna'
 incs += ' ../python ../render/extern/include #/intern/decimation/extern'
 incs += ' ../imbuf ../avi #/intern/elbeem/extern ../nodes'
 incs += ' #/intern/iksolver/extern ../blenloader ../quicktime'
-incs += ' #/extern/bullet2/src '
+incs += ' #/extern/bullet2/src'
 incs += ' #/intern/bmfont'
 
 incs += ' ' + env['BF_OPENGL_INC']
index 2dd4f1a0f0f3075d0f0ed2cfb6f9837dd131f6d2..64166493caa6a5c201bafbbda81811d00158a5e8 100644 (file)
@@ -115,7 +115,6 @@ double tval()
 static CM_SOLVER_DEF solvers [] =
 {
        { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
-       // { "Verlet", CM_VERLET, verlet_init, verlet_solver, verlet_free },
 };
 
 /* ********** cloth engine ******* */
@@ -477,8 +476,9 @@ static int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
                fclose(fp);
        }
        
-       implicit_set_positions(clmd);
-                       
+       if(clmd->sim_parms->solver_type == 0)
+               implicit_set_positions(clmd);
+               
        return ret;
 }
 
@@ -600,6 +600,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                                tstart();
                                
                                /* Call the solver. */
+                               
                                if (solvers [clmd->sim_parms->solver_type].solver)
                                        solvers [clmd->sim_parms->solver_type].solver (ob, framenr, clmd, effectors);
                                
@@ -625,6 +626,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                        if(cloth_read_cache(ob, clmd, framenr))
                                cloth_to_object (ob, result, clmd);
                }
+               else
+               {
+                       cloth_clear_cache(ob, clmd, 0);
+               }
        }
        
        return result;
index 3b8f6ddd7d843fb430a37c4f25fe7b2605201850..7d7ad4800264ed3e6baac40c588e7a3f513a7b49 100644 (file)
@@ -241,7 +241,7 @@ DO_INLINE float dot_lfvector(lfVector *fLongVectorA, lfVector *fLongVectorB, uns
        unsigned int i = 0;
        float temp = 0.0;
 // schedule(guided, 2)
-#pragma omp parallel for reduction(+: temp)
+#pragma omp parallel for reduction(+: temp) private(i)
        for(i = 0; i < verts; i++)
        {
                temp += INPR(fLongVectorA[i], fLongVectorB[i]);
@@ -558,6 +558,7 @@ DO_INLINE void mul_bfmatrix_S(fmatrix3x3 *matrix, float scalar)
                mul_fmatrix_S(matrix[i].m, scalar);
        }
 }
+
 /* SPARSE SYMMETRIC multiply big matrix with long vector*/
 /* STATUS: verified */
 DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
@@ -590,6 +591,20 @@ DO_INLINE void mul_bfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector
        
        
 }
+
+
+/* SPARSE SYMMETRIC multiply big matrix with long vector (for diagonal preconditioner) */
+/* STATUS: verified */
+DO_INLINE void mul_prevfmatrix_lfvector( float (*to)[3], fmatrix3x3 *from, lfVector *fLongVector)
+{
+       unsigned int i = 0;
+       
+       for(i = 0; i < from[0].vcount; i++)
+       {
+               mul_fmatrix_fvector(to[from[i].r], from[i].m, fLongVector[from[i].c]);
+       }
+}
+
 /* SPARSE SYMMETRIC add big matrix with big matrix: A = B + C*/
 DO_INLINE void add_bfmatrix_bfmatrix( fmatrix3x3 *to, fmatrix3x3 *from,  fmatrix3x3 *matrix)
 {
@@ -983,7 +998,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
        sub_lfvector_lfvector(r, lB, r, numverts);
        filter(r, S);
        
-       mul_bfmatrix_lfvector(p, Pinv, r);
+       mul_prevfmatrix_lfvector(p, Pinv, r);
        filter(p, S);
        
        deltaNew = dot_lfvector(r, p, numverts);
@@ -1005,7 +1020,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
                
                add_lfvector_lfvectorS(r, r, s, -alpha, numverts);
                
-               mul_bfmatrix_lfvector(h, Pinv, r);
+               mul_prevfmatrix_lfvector(h, Pinv, r);
                filter(h, S);
                
                deltaOld = deltaNew;
@@ -1013,6 +1028,7 @@ int cg_filtered_pre(lfVector *dv, fmatrix3x3 *lA, lfVector *lB, lfVector *z, fma
                deltaNew = dot_lfvector(r, h, numverts);
                
                add_lfvector_lfvectorS(p, h, p, deltaNew / deltaOld, numverts);
+               
                filter(p, S);
                
        }
@@ -1125,6 +1141,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
        }
        
        
+       /*
        if(s->type == CLOTH_SPRING_TYPE_COLLISION)
        {
                if(length < L)
@@ -1135,6 +1152,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
                }
                return;
        }
+       */
        
        // calculate force of structural + shear springs
        if(s->type != CLOTH_SPRING_TYPE_BENDING)
@@ -1150,7 +1168,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
                        VECADD(s->f, s->f, stretch_force);
 
                        // Ascher & Boxman, p.21: Damping only during elonglation
-                       mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * ((INPR(vel,extent)/length))); 
+                       mul_fvector_S(damping_force, extent, clmd->sim_parms->Cdis * 0.01 * ((INPR(vel,extent)/length))); 
                        VECADD(s->f, s->f, damping_force);
 
                        dfdx_spring_type1(s->dfdx, dir,length,L,k);
@@ -1171,12 +1189,17 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
                        mul_fvector_S(bending_force, dir, fbstar(length, L, k, cb));
                        VECADD(s->f, s->f, bending_force);
                        
-                       if(INPR(bending_force,bending_force) > 0.13*0.13)
+                       // if(INPR(bending_force,bending_force) > 0.13*0.13)
                        {
                                clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
                        }
                        
+                       
                        dfdx_spring_type2(s->dfdx, dir,length,L,k, cb);
+                       /*
+                       if(s->ij == 300 || s->kl == 300)
+                               printf("id->F[0]: %f, id->F[1]: %f, id->F[2]: %f\n", s->f[0], s->f[1], s->f[2]);
+                       */
                }
        }
 }
@@ -1192,7 +1215,7 @@ DO_INLINE int cloth_apply_spring_force(ClothModifierData *clmd, ClothSpring *s,
                {
                        sub_fmatrix_fmatrix(dFdV[s->ij].m, dFdV[s->ij].m, s->dfdv);
                        sub_fmatrix_fmatrix(dFdV[s->kl].m, dFdV[s->kl].m, s->dfdv);
-                       add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv); 
+                       add_fmatrix_fmatrix(dFdV[s->matrix_index].m, dFdV[s->matrix_index].m, s->dfdv);
                }
                else if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_BIG_FORCE))
                        return 0;
@@ -1306,7 +1329,7 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
                float speed[3] = {0.0f, 0.0f,0.0f};
                float force[3]= {0.0f, 0.0f, 0.0f};
                
-#pragma omp parallel for private (i) shared(lF)
+// #pragma omp parallel for private (i) shared(lF)
                for(i = 0; i < cloth->numverts; i++)
                {
                        float vertexnormal[3]={0,0,0};
@@ -1363,7 +1386,6 @@ void cloth_calc_force(ClothModifierData *clmd, lfVector *lF, lfVector *lX, lfVec
        }
        
        clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_BIG_FORCE;
-       
 }
 
 void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVector *lF, fmatrix3x3 *dFdV, fmatrix3x3 *dFdX, float dt, fmatrix3x3 *A, lfVector *B, lfVector *dV, fmatrix3x3 *S, lfVector *z, fmatrix3x3 *P, fmatrix3x3 *Pinv)
@@ -1375,31 +1397,23 @@ void simulate_implicit_euler(lfVector *Vnew, lfVector *lX, lfVector *lV, lfVecto
        zero_lfvector(dV, numverts);
 
        subadd_bfmatrixS_bfmatrixS(A, dFdV, dt, dFdX, (dt*dt));
-
        mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
-
        add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
        
-       // itstart();
-       
+       // TODO: unstable with quality=5 + stiffness=7000 + no zero_lfvector()
        cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
        
-       // TODO: if anyone finds a way to correct this function =>
-       // explodes with stiffness = 3000 and 16k verts + pinned at 2 corners
+       // TODO: unstable with quality=5 + stiffness=7000
        // cg_filtered_pre(dV, A, B, z, S, P, Pinv);
        
-       // itend();
-       // printf("cg_filtered calc time: %f\n", (float)itval());
-       
        // advance velocities
        add_lfvector_lfvector(Vnew, lV, dV, numverts);
        
-
        del_lfvector(dFdXmV);
 }
 
 int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors)
-{              
+{
        unsigned int i=0;
        float step=0.0f, tf=1.0f;
        Cloth *cloth = clmd->clothObject;
@@ -1418,7 +1432,10 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase
                        // update velocities with constrained velocities from pinned verts
                        if(verts [i].goal >= SOFTGOALSNAP)
                        {                       
-                               VECSUB(id->V[i], cloth->xconst[i], cloth->xold[i]);
+                               float temp[3];
+                               VECSUB(temp, cloth->xconst[i], cloth->xold[i]);
+                               VECSUB(id->z[i], temp, id->V[i]);
+                               
                                // VecMulf(id->V[i], 1.0 / dt);
                        }
                }       
@@ -1612,6 +1629,8 @@ int collisions_collision_response_static ( ClothModifierData *clmd, CollisionMod
        float v1[3], v2[3], relativeVelocity[3];
        float magrelVel = 0.0;
        float epsilon = clmd->coll_parms->epsilon;
+       
+       return 0;
 
        cloth1 = clmd->clothObject;
        
@@ -2143,7 +2162,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
        int collisions = 0, count = 0;
        float (*current_x)[3];
        Implicit_Data *id = NULL;
-       /*
+       
        if (!(((Cloth *)clmd->clothObject)->tree))
        {
                printf("No BVH found\n");
@@ -2182,7 +2201,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
        
                        // fill collision list
                        collisions += bvh_traverse ( bvh1->root, bvh2->root, &collision_list );
-       
+                       
                        // call static collision response
                        if ( collision_list )
                        {
@@ -2223,7 +2242,7 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float prevstep,
                VECADD(cloth->current_x[i], cloth->current_xold[i], cloth->current_v[i]);
        }
        //////////////////////////////////////////////
-       */
+       
        /*
        // fill collision list 
        collisions += bvh_traverse(self_bvh->root, self_bvh->root, &collision_list);
index 234a096edce5e4299c1f7bd3bc0d757951c6e6c1..b57b799001aa587a5b51f95c9e50ed864853c95f 100644 (file)
@@ -672,14 +672,12 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i
        
        /* step 2: do it */
        
-       kb= key->block.first;
-       while(kb) {
-               
+       for(kb=key->block.first; kb; kb=kb->next) {
                if(kb!=key->refkey) {
                        float icuval= kb->curval;
                        
                        /* only with value, and no difference allowed */
-                       if(icuval!=0.0f && kb->totelem==tot) {
+                       if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
                                KeyBlock *refb;
                                float weight, *weights= kb->weights;
                                
@@ -738,7 +736,6 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, i
                                }
                        }
                }
-               kb= kb->next;
        }
 }
 
@@ -1312,6 +1309,9 @@ int do_ob_key(Object *ob)
        if(ob->shapeflag & (OB_SHAPE_LOCK|OB_SHAPE_TEMPLOCK)) {
                KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
 
+               if(kb && (kb->flag & KEYBLOCK_MUTE))
+                       kb= key->refkey;
+
                if(kb==NULL) {
                        kb= key->block.first;
                        ob->shapenr= 1;
index 5d3a4332b5da96194783bd50fde1e280b595b669..1c7d235cd90ada028a4f8d6116cfd7b67a75d88a 100644 (file)
@@ -4271,7 +4271,7 @@ void psys_to_softbody(Object *ob, ParticleSystem *psys, int force_recalc)
 
        if((psys->softflag&OB_SB_ENABLE)==0) return;
 
-       if((ob->recalc&OB_RECALC_TIME)==0)
+       if(ob->recalc && (ob->recalc&OB_RECALC_TIME)==0)
                psys->softflag|=OB_SB_REDO;
 
        /* let's replace the object's own softbody with the particle softbody */
index 9492754260c4d79bd8cf773b1eff3f67030d7c32..c4ef437019eb56989e590e5dc38b159d277fe42f 100644 (file)
@@ -183,3 +183,11 @@ void BKE_ptcache_id_clear(struct ID *id, char mode, int cfra, int stack_index)
        return;
 }
 
+int BKE_ptcache_id_exist(struct ID *id, int cfra, int stack_index)
+{
+       char filename[(FILE_MAXDIR+FILE_MAXFILE)*2];
+       
+       BKE_ptcache_id_filename(id, filename, cfra, stack_index, 1, 1);
+
+       return BLI_exists(filename);
+}
index 785cf515a4272bb885f09f396a753bf2a431c549..87c09fb0ee40617e76ce92b0dcbff4087d50c163 100644 (file)
@@ -44,7 +44,7 @@ typedef struct KeyBlock {
        
        float pos;
        float curval;
-       short type, adrcode, relative, pad1;    /* relative == 0 means first key is reference */
+       short type, adrcode, relative, flag;    /* relative == 0 means first key is reference */
        int totelem, pad2;
        
        void *data;
@@ -87,5 +87,8 @@ typedef struct Key {
 #define KEY_CARDINAL    1
 #define KEY_BSPLINE     2
 
+/* keyblock->flag */
+#define KEYBLOCK_MUTE  1
+
 #endif
 
index a62e4be4015ecf14142c744baae1a59c00d78fb2..7f76cb409481f532e3b9ad2813dd53f5df1fd646 100644 (file)
@@ -85,8 +85,11 @@ static void node_composit_exec_normalize(void *data, bNode *node, bNodeStack **i
                                min = *val;
                        }
                }
+               min = MIN2(0.1, min);
+               max = MAX2(0.9, max);
+               
                mult = 1.0f/(max-min);
-
+               
                printf("min %f max %f\n", min, max);
 
                composit3_pixel_processor(node, stackbuf, in[0]->data, in[0]->vec, NULL, &min, NULL, &mult, do_normalize, CB_VAL, CB_VAL, CB_VAL);
index 9ffb7578980a94f7b549a8252010f3b9049d6415..05fed2f8fbc6218fd8a5cd52bc5be7fded211bf2 100644 (file)
@@ -410,7 +410,6 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
                                                        return;
                                                }
                                        }
-                                       efa= efa->next;
                                }
                        }
                        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
@@ -484,7 +483,7 @@ void do_common_editbuts(unsigned short event) // old name, is a mix of object an
                if(ma) {
                        ob->actcol= find_material_index(ob, ma);
                        if(ob->actcol==0) {
-                               assign_material(ob, ma, ob->totcol);
+                               assign_material(ob, ma, ob->totcol+1);
                                ob->actcol= ob->totcol;
                        }
                }
@@ -2474,15 +2473,17 @@ static void editing_panel_shapes(Object *ob)
        uiBlockBeginAlign(block);
        if(ob->shapeflag & OB_SHAPE_LOCK) icon= ICON_PIN_HLT; else icon= ICON_PIN_DEHLT;
        uiDefIconButBitS(block, TOG, OB_SHAPE_LOCK, B_LOCKKEY, icon, 10,150,25,20, &ob->shapeflag, 0, 0, 0, 0, "Always show the current Shape for this Object");
+       if(kb->flag & KEYBLOCK_MUTE) icon= ICON_MUTE_IPO_ON; else icon = ICON_MUTE_IPO_OFF;
+       uiDefIconButBitS(block, TOG, KEYBLOCK_MUTE, B_MODIFIER_RECALC, icon, 35,150,20,20, &kb->flag, 0, 0, 0, 0, "Mute the current Shape");
        uiSetButLock(G.obedit==ob, "Unable to perform in EditMode");
-       uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT,             35,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
+       uiDefIconBut(block, BUT, B_PREVKEY, ICON_TRIA_LEFT,             55,150,20,20, NULL, 0, 0, 0, 0, "Previous Shape Key");
        strp= make_key_menu(key, 1);
-       uiDefButS(block, MENU, B_SETKEY, strp,                                  55,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
+       uiDefButS(block, MENU, B_SETKEY, strp,                                  75,150,20,20, &ob->shapenr, 0, 0, 0, 0, "Browse existing choices");
        MEM_freeN(strp);
        
-       uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT,    75,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
+       uiDefIconBut(block, BUT, B_NEXTKEY, ICON_TRIA_RIGHT,    95,150,20,20, NULL, 0, 0, 0, 0, "Next Shape Key");
        uiClearButLock();
-       uiDefBut(block, TEX, B_NAMEKEY, "",                                             95, 150, 190, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
+       uiDefBut(block, TEX, B_NAMEKEY, "",                                             115, 150, 170, 20, kb->name, 0.0, 31.0, 0, 0, "Current Shape Key name");
        uiDefIconBut(block, BUT, B_DELKEY, ICON_X,                              285,150,25,20, 0, 0, 0, 0, 0, "Deletes current Shape Key");
        uiBlockEndAlign(block);
 
index e7a2a654ba1f9e21bf719294d2ce068819e72eea..3360dab61f8e7ecccc7045f7182556674919dd38 100644 (file)
@@ -3298,6 +3298,7 @@ static void object_softbodies__enable(void *ob_v, void *arg2)
                if (!ob->soft) {
                        ob->soft= sbNew();
                        ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
+                       softbody_clear_cache(ob, CFRA);
                }
        }
        /* needed so that initial state is cached correctly */
@@ -3331,6 +3332,7 @@ static void object_softbodies__enable_psys(void *ob_v, void *psys_v)
                        psys->soft= sbNew();
                        psys->softflag |= OB_SB_GOAL|OB_SB_EDGES;
                        psys->soft->particles=psys;
+                       clear_particles_from_cache(ob, psys, CFRA);
                }
                psys->softflag |= OB_SB_ENABLE;
        }
index 14690b08d480da47a937232d379c9e893c2e3199..93915a0e92ef72bf5a134c5d59a02107f323bcd3 100644 (file)
@@ -70,6 +70,8 @@
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_meta_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_force.h"
 #include "DNA_object_types.h"
 #include "DNA_particle_types.h"
 #include "DNA_screen_types.h"
 #include "BKE_key.h"
 #include "BKE_main.h"
 #include "BKE_mesh.h"
+#include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
+#include "BKE_pointcache.h"
 #include "BKE_scene.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
@@ -3292,10 +3296,50 @@ static void inner_play_prefetch_shutdown(int mode)
        seq_stop_threads();
 }
 
+static int cached_dynamics(int sfra, int efra)
+{
+       Base *base = G.scene->base.first;
+       Object *ob;
+       ModifierData *md;
+       ParticleSystem *psys;
+       int i, stack_index, cached=1;
+
+       while(base && cached) {
+               ob = base->object;
+               if(ob->softflag & OB_SB_ENABLE && ob->soft) {
+                       for(i=0, md=ob->modifiers.first; md; i++, md=md->next) {
+                               if(md->type == eModifierType_Softbody) {
+                                       stack_index = i;
+                                       break;
+                               }
+                       }
+                       for(i=sfra; i<=efra && cached; i++)
+                               cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
+               }
+
+               for(psys=ob->particlesystem.first; psys; psys=psys->next) {
+                       stack_index = modifiers_indexInObject(ob,(ModifierData*)psys_get_modifier(ob,psys));
+                       if(psys->part->type==PART_HAIR) {
+                               if(psys->softflag & OB_SB_ENABLE && psys->soft);
+                               else
+                                       stack_index = -1;
+                       }
+
+                       if(stack_index >= 0)
+                               for(i=sfra; i<=efra && cached; i++)
+                                       cached &= BKE_ptcache_id_exist(&ob->id,i,stack_index);
+               }
+               
+               base = base->next;
+       }
+
+       return cached;
+}
 void inner_play_anim_loop(int init, int mode)
 {
        ScrArea *sa;
        static int last_cfra = -1;
+       static int cached = 0;
 
        /* init */
        if(init) {
@@ -3304,7 +3348,7 @@ void inner_play_anim_loop(int init, int mode)
                tottime= 0.0;
                curmode= mode;
                last_cfra = -1;
-
+               cached = cached_dynamics(PSFRA,PEFRA);
                return;
        }
 
@@ -3328,7 +3372,7 @@ void inner_play_anim_loop(int init, int mode)
                                if (sa->spacetype == SPACE_SEQ) {
                                        scrarea_do_windraw(sa);
                                }
-                       }               
+                       }
                
                        sa= sa->next;   
                }
@@ -3380,8 +3424,10 @@ void inner_play_anim_loop(int init, int mode)
                CFRA = PSFRA;
                audiostream_stop();
                audiostream_start( CFRA );
+               cached = cached_dynamics(PSFRA,PEFRA);
        } else {
-               if (U.mixbufsize 
+               if (cached
+                       && U.mixbufsize 
                    && (G.scene->audio.flag & AUDIO_SYNC)) {
                        CFRA = audiostream_pos();
                } else {
index 0d861cda5d091705f7184e8e2ba9b94e1dea257b..5cc193f88444eda669725c7011f278baed1605fc 100644 (file)
@@ -625,7 +625,7 @@ void insert_shapekey(Object *ob)
 
 void delete_key(Object *ob)
 {
-       KeyBlock *kb;
+       KeyBlock *kb, *rkb;
        Key *key;
        IpoCurve *icu;
        
@@ -635,6 +635,10 @@ void delete_key(Object *ob)
        kb= BLI_findlink(&key->block, ob->shapenr-1);
 
        if(kb) {
+               for(rkb= key->block.first; rkb; rkb= rkb->next)
+                       if(rkb->relative == ob->shapenr-1)
+                               rkb->relative= 0;
+
                BLI_remlink(&key->block, kb);
                key->totkey--;
                if(key->refkey== kb) key->refkey= key->block.first;
index ae10cef08794b5f35ab7c51ac38add9366d936d9..a74bd851aeb0a167c1372b3db5eb973b0564ac94 100644 (file)
@@ -82,6 +82,7 @@ editmesh_mods.c, UI level access, no geometry changes
 #include "BIF_interface.h"
 #include "BIF_meshtools.h"
 #include "BIF_mywindow.h"
+#include "BIF_previewrender.h"
 #include "BIF_resources.h"
 #include "BIF_screen.h"
 #include "BIF_space.h"
@@ -2126,6 +2127,12 @@ void mouse_mesh(void)
                        allqueue(REDRAWIMAGE, 0);
                        allqueue(REDRAWBUTSEDIT, 0); /* for the texture face panel */
                }
+               if (efa && efa->mat_nr != G.obedit->actcol-1) {
+                       G.obedit->actcol= efa->mat_nr+1;
+                       allqueue(REDRAWBUTSEDIT, 0);
+                       allqueue(REDRAWBUTSSHADING, 0);
+                       BIF_preview_changed(ID_MA);
+               }
        }
 
        rightmouse_transform();
index e08ca3279d64e5a09b69637496b48967e1eb2a03..c9cf745fa441e7c30373f60a5738c2b5ef7936da 100644 (file)
@@ -1703,10 +1703,10 @@ static int remove_tagged_elements(Object *ob, ParticleSystem *psys)
                        }
                }
 
-               MEM_freeN(psys->particles);
+               if(psys->particles) MEM_freeN(psys->particles);
                psys->particles = new_pars;
 
-               MEM_freeN(edit->keys);
+               if(edit->keys) MEM_freeN(edit->keys);
                edit->keys = new_keys;
 
                if(edit->mirror_cache) {
@@ -2256,10 +2256,10 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
                memcpy(new_keys, edit->keys, totpart * sizeof(ParticleEditKey*));
 
                /* change old arrays to new ones */
-               MEM_freeN(psys->particles);
+               if(psys->particles) MEM_freeN(psys->particles);
                psys->particles = new_pars;
 
-               MEM_freeN(edit->keys);
+               if(edit->keys) MEM_freeN(edit->keys);
                edit->keys = new_keys;
 
                if(edit->mirror_cache) {
@@ -2267,8 +2267,6 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
                        edit->mirror_cache = NULL;
                }
 
-               psys->totpart = newtotpart;
-               
                /* create tree for interpolation */
                if(pset->flag & PE_INTERPOLATE_ADDED && psys->totpart){
                        tree=BLI_kdtree_new(psys->totpart);
@@ -2281,6 +2279,8 @@ static void brush_add(Object *ob, ParticleSystem *psys, short *mval, short numbe
                        BLI_kdtree_balance(tree);
                }
 
+               psys->totpart = newtotpart;
+
                /* create new elements */
                pa = psys->particles + totpart;
                key = edit->keys + totpart;
@@ -2691,10 +2691,10 @@ void PE_mirror_x(int tagged)
                memcpy(new_pars, psys->particles, totpart*sizeof(ParticleData));
                memcpy(new_keys, edit->keys, totpart*sizeof(ParticleEditKey*));
 
-               MEM_freeN(psys->particles);
+               if(psys->particles) MEM_freeN(psys->particles);
                psys->particles= new_pars;
 
-               MEM_freeN(edit->keys);
+               if(edit->keys) MEM_freeN(edit->keys);
                edit->keys= new_keys;
 
                if(edit->mirror_cache) {