Cloth: 1. Bugfix for possible memory leak reported by Kenneth Styrberg (via mailing...
authorDaniel Genrich <daniel.genrich@gmx.net>
Thu, 28 Feb 2008 00:01:19 +0000 (00:01 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Thu, 28 Feb 2008 00:01:19 +0000 (00:01 +0000)
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenloader/intern/readfile.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/src/buttons_object.c
source/blender/src/editmesh.c

index 8dc84f5945ec9258e7ab8750c7f108c2be8d96f1..f5bd028ba0d23bbd6d047073a05bf5b4a798111b 100644 (file)
@@ -148,6 +148,7 @@ typedef enum
        CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE = ( 1 << 7 ), /* force cache freeing */
        CLOTH_SIMSETTINGS_FLAG_SCALING = ( 1 << 8 ), /* is advanced scaling active? */
        CLOTH_SIMSETTINGS_FLAG_LOADED = ( 1 << 9 ), /* did we just got load? */
+       CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT = ( 1 << 10 ), /* is autoprotect enabled? */
 } CLOTH_SIMSETTINGS_FLAGS;
 
 /* COLLISION FLAGS */
index b1849f8b69347d30b76829d23888e5a13def05eb..d78a9f51f77cc47e25bfc536d2da9ab34981c7e5 100644 (file)
@@ -152,7 +152,7 @@ void cloth_init ( ClothModifierData *clmd )
        clmd->sim_parms->mass = 1.0f;
        clmd->sim_parms->stepsPerFrame = 5;
        clmd->sim_parms->sim_time = 1.0;
-       clmd->sim_parms->flags = 0;
+       clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT;
        clmd->sim_parms->solver_type = 0;
        clmd->sim_parms->preroll = 0;
        clmd->sim_parms->maxspringlen = 10;
@@ -164,6 +164,7 @@ void cloth_init ( ClothModifierData *clmd )
        clmd->sim_parms->autoprotect = 25;
        clmd->sim_parms->firstcachedframe = -1.0;
        clmd->sim_parms->avg_spring_len = 0.0;
+       clmd->sim_parms->presets = 2; /* cotton as start setting */
        
        clmd->coll_parms->self_friction = 5.0;
        clmd->coll_parms->friction = 5.0;
@@ -232,7 +233,6 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
        bvh->numverts = cloth->numverts;
        
        bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" );
-       bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
        
        if (bvh->current_x == NULL) 
        {
@@ -241,9 +241,12 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
                return NULL;
        }
        
+       bvh->current_xold = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_xold" );
+       
        if (bvh->current_xold == NULL) 
        {
                printf("bvh: Out of memory.\n");
+               MEM_freeN(bvh->current_x);
                MEM_freeN(bvh);
                return NULL;
        }
@@ -574,6 +577,10 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                cloth_free_modifier (ob, clmd);
                if(G.rt > 0)
                        printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n");
+               
+               // prevent rebuilding of cloth each time you move backward 
+               if(deltaTime < 0.0)
+                       return result;
        }
        
        // unused in the moment, calculated seperately in implicit.c
@@ -656,20 +663,22 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
        }
        
        // check for autoprotection, but only if cache active
-       if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
+       if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
        {
-               if(G.rt > 0)
-                       printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
-               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
+               if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
+               {
+                       if(G.rt > 0)
+                               printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
+                       
+                       clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
+               }
        }
-       if(G.rt > 0)
-               printf("clothModifier_do deltaTime=1 cachewrite\n");
        
        /* nice moving one frame forward */
        if ( deltaTime == 1.0f )
        {
                clmd->sim_parms->sim_time = current_time;
-               
+                       
                if(G.rt > 0)
                        printf("clothModifier_do deltaTime=1\n");
                
@@ -718,7 +727,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
        else if(deltaTime == 0.0f) 
        {       
                if(G.rt > 0)
-                       printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n");
+                       printf("dt = 0, %f\n", framenr);
                if(cloth_read_cache(ob, clmd, framenr))
                {
                        cloth_to_object (ob, clmd, result);
@@ -726,30 +735,35 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d
                }
                else /* same cache parts are missing */
                {
-                       /*
-                       clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
-                       */
-                       clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
-                       cloth_clear_cache(ob, clmd, 0);
-                       
-                       cloth_write_cache(ob, clmd, framenr);
+                       /* jump to a non-existing frame makes sim reset if cache is not protected */
+                       if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+                       {       
+                               /*
+                               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+                               */
+                               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
+                               cloth_clear_cache(ob, clmd, 0);
+                               
+                               cloth_write_cache(ob, clmd, framenr);
+                       }
                }
        }
        else
        {       
                if(G.rt > 0)
-                       printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n");
+                       printf("dt > 1.0 || dt < 0.0, %f\n", framenr);
                if(cloth_read_cache(ob, clmd, framenr))
                {
                        cloth_to_object (ob, clmd, result);
                        implicit_set_positions(clmd);
-                       clmd->sim_parms->sim_time = current_time;
                }
                else
                {
-                       /* jump to a non-existing frame makes sim reset */
-                       clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
+                       /* jump to a non-existing frame makes sim reset if cache is not protected */
+                       if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
+                               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
                }
+               clmd->sim_parms->sim_time = current_time;
        }
        
        return result;
index 6ef6758cab671acf407e8ac77fe9a8e0fb1a1fe8..de13d952f8ea49705028d15aaba860edeb5b3643 100644 (file)
@@ -478,7 +478,7 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
                
                interpolateOnTriangle(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, u1, u2, u3);
                
-               VECSUB(relativeVelocity, v1, v2);
+               VECSUB(relativeVelocity, v2, v1);
                        
                // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
                magrelVel = INPR(relativeVelocity, collpair->normal);
@@ -489,10 +489,10 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
                // TODO
                
                // If v_n_mag < 0 the edges are approaching each other.
-               if(magrelVel < -ALMOST_ZERO) 
+               if(magrelVel ALMOST_ZERO) 
                {
                        // Calculate Impulse magnitude to stop all motion in normal direction.
-                       float magtangent;
+                       float magtangent = 0, repulse = 0, d = 0;
                        double impulse = 0.0;
                        float vrel_t_pre[3];
                        float temp[3];
@@ -502,21 +502,25 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
                        VecMulf(temp, magrelVel);
                        VECSUB(vrel_t_pre, relativeVelocity, temp);
                        
-                       magtangent = INPR(vrel_t_pre,vrel_t_pre) - MIN2(clmd->coll_parms->friction * 0.01 * magrelVel,INPR(vrel_t_pre,vrel_t_pre));
+                       // Decrease in magnitude of relative tangential velocity due to coulomb friction
+                       // in original formula "magrelVel" should be the "change of relative velocity in normal direction" 
+                       magtangent = MIN2(clmd->coll_parms->friction * 0.01 * magrelVel,sqrt(INPR(vrel_t_pre,vrel_t_pre)));
                        
                        // Apply friction impulse.
                        if (magtangent > ALMOST_ZERO) 
                        {       
                                Normalize(vrel_t_pre);
-
-                               impulse = -2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+                               
+                               impulse = 2.0 * magtangent / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
                                VECADDMUL(cloth1->verts[collpair->ap1].impulse, vrel_t_pre, w1 * impulse);
                                VECADDMUL(cloth1->verts[collpair->ap2].impulse, vrel_t_pre, w2 * impulse);
                                VECADDMUL(cloth1->verts[collpair->ap3].impulse, vrel_t_pre, w3 * impulse);
                        }
                        
-
-                       impulse = -2.0f * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3);
+                       // Apply velocity stopping impulse
+                       // I_c = m * v_N / 2.0
+                       // no 2.0 * magrelVel normally, but looks nicer DG
+                       impulse =  2.0 * magrelVel / ( 1.0 + w1*w1 + w2*w2 + w3*w3); 
                        
                        VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse); 
                        cloth1->verts[collpair->ap1].impulse_count++;
@@ -527,6 +531,22 @@ int cloth_collision_response_static(ClothModifierData *clmd, CollisionModifierDa
                        VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse); 
                        cloth1->verts[collpair->ap3].impulse_count++;
                        
+                       /*
+                       // doesn't perform nice, dunno why DG
+                       // Apply repulse impulse if distance too short
+                       // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+                       d = clmd->coll_parms->epsilon - collpair->distance;
+                       if((magrelVel < 0.1*d*clmd->sim_parms->stepsPerFrame) && (d > ALMOST_ZERO))
+                       {
+                               repulse = MIN2(d*5.0/clmd->sim_parms->stepsPerFrame, 0.1*d*clmd->sim_parms->stepsPerFrame - magrelVel);
+                               
+                               impulse = 0.25 * repulse / ( 1.0 + w1*w1 + w2*w2 + w3*w3); // original 2.0 / 0.25
+                               VECADDMUL(cloth1->verts[collpair->ap1].impulse, collpair->normal, w1 * impulse);
+                               VECADDMUL(cloth1->verts[collpair->ap2].impulse, collpair->normal, w2 * impulse);
+                               VECADDMUL(cloth1->verts[collpair->ap3].impulse, collpair->normal, w3 * impulse);
+                       }
+                       */
+                       
                        result = 1;
                }
                
@@ -1023,7 +1043,10 @@ int cloth_bvh_objcollision(ClothModifierData * clmd, float step, float dt)
                                bvh_traverse((ModifierData *)clmd, (ModifierData *)collmd, cloth_bvh->root, coll_bvh->root, step, cloth_collision_static, 0);
                        }
                        else
+                       {
+                               if(G.rt > 0)
                                printf ("cloth_bvh_objcollision: found a collision object with clothObject or collData NULL.\n");
+                       }
                
                
                        // process all collisions (calculate impulses, TODO: also repulses if distance too short)
index da0bed50592662d77f4b2eafbf070bcca0befcc0..d9d1a41bb535f1d7767dac6659b296258212c536 100644 (file)
@@ -878,7 +878,7 @@ DO_INLINE float fbstar(float length, float L, float kb, float cb)
        float tempfb = kb * fb(length, L);
 
        float fbstar = cb * (length - L);
-
+       
        if(tempfb < fbstar)
                return fbstar;
        else
index 6feb0d1cc2dfffbdd476b2e2a83c85b440993bd5..66d3fcd4729d3f0600d01a77618ca79b7840f7e1 100644 (file)
@@ -3037,6 +3037,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
                        clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_LOADED;
                        clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
                        
+                       if(clmd->sim_parms->presets > 10)
+                               clmd->sim_parms->presets = 0;
+                       
                }
                else if (md->type==eModifierType_Collision) {
                        
index 40abe012a5a17e587ac1470226cc53f4dcd9ac0a..4ba1f4f02e868c4bf637d29cc08b43876cce5230 100644 (file)
@@ -83,6 +83,9 @@ typedef struct SimulationSettings
        float   max_shear;      /* max shear scaling value, UNUSED */
        int     firstcachedframe;
        float   avg_spring_len; /* used for normalized springs */
+       short   presets; /* used for presets on GUI */
+       short pad;
+       int pad2;
 }
 SimulationSettings;
 
index da06351404ec9203050f29ad1eaf1cfa8f6b6fb4..a09da0b99900c44fb26ba0ba971a21e15b068d46 100644 (file)
@@ -5123,6 +5123,54 @@ static void object_cloth__enabletoggle(void *ob_v, void *arg2)
        }
 }
 
+static void cloth_presets_material(void *ob_v, void *arg2)
+{
+       Object *ob = ob_v;
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+       
+       if(!clmd) return;
+       if(clmd->sim_parms->presets==0) return;
+       
+       if(clmd->sim_parms->presets==1) /* SILK */
+       {
+               clmd->sim_parms->structural = clmd->sim_parms->shear = 30.0;
+               clmd->sim_parms->bending = 0.1;
+       }
+       else if(clmd->sim_parms->presets==2) /* COTTON */
+       {
+               clmd->sim_parms->structural = clmd->sim_parms->shear = 30.0;
+               clmd->sim_parms->bending = 1.0;
+       }
+       else if(clmd->sim_parms->presets==3) /* RUBBER */
+       {
+               clmd->sim_parms->structural = clmd->sim_parms->shear = 5.0;
+               clmd->sim_parms->bending = 25.0;
+               clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 7.0);
+       }
+       else if(clmd->sim_parms->presets==4) /* DENIM */
+       {
+               clmd->sim_parms->structural = clmd->sim_parms->shear = 70.0;
+               clmd->sim_parms->bending = 300.0;
+               clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 15.0);
+       }
+       else if(clmd->sim_parms->presets==5) /* LEATHER */
+       {
+               clmd->sim_parms->structural = clmd->sim_parms->shear = 1000.0;
+               clmd->sim_parms->bending = 2500.0;
+               clmd->sim_parms->stepsPerFrame = MAX2(clmd->sim_parms->stepsPerFrame, 25.0);
+       }
+}
+
+static void cloth_presets_custom_material(void *ob_v, void *arg2)
+{
+       Object *ob = ob_v;
+       ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+       
+       if(!clmd) return;
+       
+       clmd->sim_parms->presets = 0;
+}
+
 static int _can_cloth_at_all(Object *ob)
 {
        // list of Yes
@@ -5166,28 +5214,37 @@ static void object_panel_cloth(Object *ob)
                
                /* GENERAL STUFF */
                uiClearButLock();
-               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+               else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+               
+               uiDefBut(block, LABEL, 0, "Material Preset:",  10,170,150,20, NULL, 0.0, 0, 0, 0, "");
+               but=uiDefButS(block, MENU, B_CLOTH_RENEW, "Silk %x1|Cotton %x2|Rubber %x3|Denim %x4|Leather %x5|Custom %x0",
+                            160,170,150,20, &clmd->sim_parms->presets, 0, 0, 0, 0, "");
+               uiButSetFunc(but, cloth_presets_material, ob, NULL);
                
                uiBlockBeginAlign(block);
-               uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,170,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
-               uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,170,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
-               uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,150,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
+               but = uiDefButF(block, NUM, B_CLOTH_RENEW, "StructStiff:", 10,150,150,20, &clmd->sim_parms->structural, 1.0, 10000.0, 100, 0, "Overall stiffness of structure");
+               uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
+               
+               but = uiDefButF(block, NUM, B_CLOTH_RENEW, "BendStiff:", 160,150,150,20, &clmd->sim_parms->bending, 0.0, 10000.0, 1000, 0, "Wrinkle coefficient (higher = less smaller but more big wrinkles)");
+               uiButSetFunc(but, cloth_presets_custom_material, ob, NULL);
+               
+               uiDefButI(block, NUM, B_CLOTH_RENEW, "Quality:", 10,130,150,20, &clmd->sim_parms->stepsPerFrame, 4.0, 80.0, 5, 0, "Quality of the simulation (higher=better=slower)");
 
-               uiDefButF(block, NUM, B_CLOTH_RENEW, "Spring Damp:", 160,150,150,20, &clmd->sim_parms->Cdis, 0.0, 1.0, 10, 0, "Spring damping");
-               uiDefButF(block, NUM, B_DIFF, "Air Damp:", 10,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
+               uiDefButF(block, NUM, B_CLOTH_RENEW, "Air Damp:", 160,130,150,20, &clmd->sim_parms->Cvi, 0.0, 10.0, 10, 0, "Air has normaly some thickness which slows falling things down");
                
-               uiDefBut(block, LABEL, 0, "Gravity:",  10,100,60,20, NULL, 0.0, 0, 0, 0, "");
+               uiDefBut(block, LABEL, 0, "Gravity:",  10,110,60,20, NULL, 0.0, 0, 0, 0, "");
                
-               uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,100,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
-               uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,100,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
-               uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,100,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+               uiDefButF(block, NUM, B_CLOTH_RENEW, "X:", 70,110,80,20, &clmd->sim_parms->gravity[0], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+               uiDefButF(block, NUM, B_CLOTH_RENEW, "Y:", 150,110,80,20, &clmd->sim_parms->gravity[1], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
+               uiDefButF(block, NUM, B_CLOTH_RENEW, "Z:", 230,110,80,20, &clmd->sim_parms->gravity[2], -100.0, 100.0, 10, 0, "Apply gravitation to point movement");
                uiBlockEndAlign(block);
                
                /* GOAL STUFF */
                uiBlockBeginAlign(block);
                
                
-               uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth",        10,70,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
+               uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_GOAL, B_CLOTH_RENEW, "Pinning of cloth",        10,80,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Define forces for vertices to stick to animated position");
                
                if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL) && (BLI_countlist (&ob->defbase) > 0))
                {
@@ -5216,13 +5273,13 @@ static void object_panel_cloth(Object *ob)
                                                        
                                sprintf (clvg2, "%s%s", clmvg, clvg1);
                                
-                               uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,70,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
+                               uiDefButS(block, MENU, B_CLOTH_RENEW, clvg2, 160,80,150,20, &clmd->sim_parms->vgroup_mass, 0, defCount, 0, 0, "Browses available vertex groups");
                                MEM_freeN (clvg1);
                                MEM_freeN (clvg2);
                        }
                        
-                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,50,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
-                       uiDefBut(block, LABEL, 0, "",160,50,150,20, NULL, 0.0, 0, 0, 0, "");    
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Pin Stiff:", 10,60,150,20, &clmd->sim_parms->goalspring, 0.0, 50.0, 50, 0, "Pin (vertex target position) spring stiffness");
+                       uiDefBut(block, LABEL, 0, "",160,60,150,20, NULL, 0.0, 0, 0, 0, "");    
                        // uiDefButI(block, NUM, B_CLOTH_RENEW, "Pin Damp:", 160,50,150,20, &clmd->sim_parms->goalfrict, 1.0, 100.0, 10, 0, "Pined damping (higher = doesn't oszilate so much)");
                        /*
                        // nobody is changing these ones anyway
@@ -5232,7 +5289,7 @@ static void object_panel_cloth(Object *ob)
                }
                else if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL)
                {
-                       uiDefBut(block, LABEL, 0, " ",  160,70,150,20, NULL, 0.0, 0, 0, 0, "");
+                       uiDefBut(block, LABEL, 0, " ",  160,80,150,20, NULL, 0.0, 0, 0, 0, "");
                        uiDefBut(block, LABEL, 0, "No vertex group for pinning available.",  10,50,300,20, NULL, 0.0, 0, 0, 0, "");
                }
                
@@ -5296,14 +5353,20 @@ static void object_panel_cloth_II(Object *ob)
        if(clmd)
        {       
                uiClearButLock();
-               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+               else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
                
                uiDefButI(block, NUM, B_CLOTH_RENEW, "First Frame:",10,160,150,20, &clmd->sim_parms->firstframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation starts");
                uiDefButI(block, NUM, B_CLOTH_RENEW, "Last Frame:",160,160,150,20, &clmd->sim_parms->lastframe, 0, MAXFRAME, 1, 0, "Frame on which the simulation stops");
                
                uiDefBut(block, LABEL, 0, "",10,140,300,20, NULL, 0.0, 0, 0, 0, "");
-               uiClearButLock();
-               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+               
+               if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE))
+               {
+                       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)
+                               uiClearButLock();
+               }
+               
                if (!G.relbase_valid)
                {
                        uiDefBut(block, LABEL, 0, "Cache deactivated until file is saved.",  10,120,300,20, NULL, 0.0, 0, 0, 0, "");
@@ -5319,8 +5382,11 @@ static void object_panel_cloth_II(Object *ob)
                        uiDefBut(block, LABEL, 0, " ",  10,80,300,20, NULL, 0.0, 0, 0, 0, "");
                }
                
-               uiClearButLock();
-               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+               if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE))
+               {
+                       if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) 
+                               uiSetButLock(1, "Cache is protected");
+               }
                
                /*
                TODO: implement this again in cloth!
@@ -5333,16 +5399,16 @@ static void object_panel_cloth_II(Object *ob)
                uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_ENABLED, B_CLOTH_RENEW, "Enable collisions",   10,60,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable collisions with this object");
                if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED)
                {
-                       uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:",           160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
-                       uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Collision Quality:",      10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame");
-                       uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Friction:",       160,40,150,20, &clmd->coll_parms->friction, 0.0, 80.0, 1.0, 0, "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:",      160,60,150,20, &clmd->coll_parms->epsilon, 0.001f, 1.0, 0.01f, 0, "Minimum distance between collision objects before collision response takes in, can be changed for each frame");
+                       uiDefButS(block, NUM, B_CLOTH_RENEW, "Collision Quality:",         10,40,150,20, &clmd->coll_parms->loop_count, 1.0, 20.0, 1.0, 0, "How many collision iterations should be done. (higher = better = slower), can be changed for each frame");
+                       uiDefButF(block, NUM, B_CLOTH_RENEW, "Friction:",          160,40,150,20, &clmd->coll_parms->friction, 0.0, 80.0, 1.0, 0, "Friction force if a collision happened (0=movement not changed, 100=no movement left)");
                        
                        uiDefButBitI(block, TOG, CLOTH_COLLSETTINGS_FLAG_SELF, B_CLOTH_RENEW, "Enable selfcollisions",  10,20,150,20, &clmd->coll_parms->flags, 0, 0, 0, 0, "Enable selfcollisions with this object");
                        if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF)     
                        {
-                               uiDefButF(block, NUM, REDRAWBUTSOBJECT, "Min Distance:",           160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
+                               uiDefButF(block, NUM, B_CLOTH_RENEW, "Min Distance:",      160,20,150,20, &clmd->coll_parms->selfepsilon, 0.5f, 1.0, 0.01f, 0, "0.5 means no distance at all, 1.0 is maximum distance");
                                // self_loop_count
-                               uiDefButS(block, NUM, REDRAWBUTSOBJECT, "Selfcoll Quality:",       10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
+                               uiDefButS(block, NUM, B_CLOTH_RENEW, "Selfcoll Quality:",          10,0,150,20, &clmd->coll_parms->self_loop_count, 1.0, 10.0, 1.0, 0, "How many selfcollision iterations should be done. (higher = better = slower), can be changed for each frame");
                        }
                        else
                                uiDefBut(block, LABEL, 0, "",160,20,150,20, NULL, 0.0, 0, 0, 0, "");    
@@ -5379,10 +5445,19 @@ static void object_panel_cloth_III(Object *ob)
                char clmvg2 [] = "Vertex Groups%t|None%x0|";
                
                uiClearButLock();
-               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
+               if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) uiSetButLock(1, "Please leave editmode.");
+               else if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT) uiSetButLock(1, "Cache is protected");
                
+               uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT, REDRAWBUTSOBJECT, "Autoprotect cache",10,160,150,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "Enables automatic toggling of the 'Protect cache' button from the 2nd panel.");
                
-               uiDefButI(block, NUM, B_DIFF, "Autoprotect Cache From:",10,160,300,20, &clmd->sim_parms->autoprotect, 0.0, MAXFRAME + 1, 1, 0, "Frame on which the simulation gets cache protection enabled automatically (To prevent accidently cleaning it).");
+               if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
+               {
+                       uiDefButI(block, NUM, B_DIFF, "From frame:",160,160,150,20, &clmd->sim_parms->autoprotect, 0.0, MAXFRAME + 1, 1, 0, "Frame on which the 'Protect Cache' button (2nd panel) is toggled automatically (To prevent accidently cleaning it).");
+               }
+               else
+               {
+                       uiDefBut(block, LABEL, 0, " ",  160,160,150,20, NULL, 0.0, 0, 0, 0, "");
+               }
                                
                uiDefButBitI(block, TOG, CLOTH_SIMSETTINGS_FLAG_SCALING, B_CLOTH_RENEW, "Enable stiffness scaling",10,130,300,20, &clmd->sim_parms->flags, 0, 0, 0, 0, "If enabled, stiffness can be scaled along a weight painted vertex group.");
                
index acb4134a0400cbad6fec1d05c5810a98115e3cb7..34d3bc89bdbac1a772f9320f5d07052bdfb4ea75 100644 (file)
@@ -854,6 +854,8 @@ void make_editMesh()
                clmd = (ClothModifierData *) modifiers_findByType(G.obedit, eModifierType_Cloth);
                cloth = clmd->clothObject;
                
+               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE;
+               
                /* just to be sure also check vertcount */
                /* also check if we have a protected cache */
                if(cloth && (tot == cloth->numverts) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
@@ -866,7 +868,6 @@ void make_editMesh()
                                cloth_enabled = 1;
                                
                                clmd->sim_parms->editedframe = G.scene->r.cfra;
-                               clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_EDITMODE;
                                
                                /* inverse matrix is not uptodate... */
                                Mat4Invert ( G.obedit->imat, G.obedit->obmat );
@@ -1179,8 +1180,14 @@ void load_editMesh(void)
                if(G.rt > 0)
                printf("loadmesh --> cloth_enabled cloth_write_cache\n");
                cloth_write_cache(G.obedit, clmd, clmd->sim_parms->editedframe);
-               cloth_read_cache(G.obedit, clmd, G.scene->r.cfra);
-               implicit_set_positions(clmd);
+               
+               if(G.scene->r.cfra != clmd->sim_parms->editedframe)
+               {
+                       if(cloth_read_cache(G.obedit, clmd, G.scene->r.cfra))
+                               implicit_set_positions(clmd);
+               }
+               else
+                       implicit_set_positions(clmd);
                
                clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_EDITMODE;
        }
@@ -1470,6 +1477,7 @@ void remake_editMesh(void)
 {
        make_editMesh();
        allqueue(REDRAWVIEW3D, 0);
+       allqueue(REDRAWBUTSOBJECT, 0); /* needed to have nice cloth panels */
        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
        BIF_undo_push("Undo all changes");
 }