diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-02-28 03:01:19 +0300 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-02-28 03:01:19 +0300 |
commit | 905a2d374a9b418fe2d358f4c7fdbc12a6253f91 (patch) | |
tree | 11fd4523fd432d9fce60e6f73827f056a7d9f176 /source/blender | |
parent | 62bd1b85e63d996dbe1c50fe5a47df236001e147 (diff) |
Cloth: 1. Bugfix for possible memory leak reported by Kenneth Styrberg (via mailing list), 2. Bugfix for friction again, 3. Preset menu on GUI (thanks to help from nudelZ (#blendercoders), 4. Possibility to disable autoprotect cache, 5. Some cache bugs fixed, 6. Some speedup in generating cloth
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_cloth.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cloth.c | 56 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/collision.c | 39 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/implicit.c | 2 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_cloth_types.h | 3 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 129 | ||||
-rw-r--r-- | source/blender/src/editmesh.c | 14 |
8 files changed, 187 insertions, 60 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8dc84f5945e..f5bd028ba0d 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -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 */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index b1849f8b693..d78a9f51f77 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -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; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6ef6758cab6..de13d952f8e 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -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) diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index da0bed50592..d9d1a41bb53 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -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 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6feb0d1cc2d..66d3fcd4729 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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) { diff --git a/source/blender/makesdna/DNA_cloth_types.h b/source/blender/makesdna/DNA_cloth_types.h index 40abe012a5a..4ba1f4f02e8 100644 --- a/source/blender/makesdna/DNA_cloth_types.h +++ b/source/blender/makesdna/DNA_cloth_types.h @@ -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; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index da06351404e..a09da0b9990 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -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."); diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c index acb4134a040..34d3bc89bdb 100644 --- a/source/blender/src/editmesh.c +++ b/source/blender/src/editmesh.c @@ -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"); } |