From 77685023caaee092a4c1ed4a3da13ff67861a962 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 29 Jan 2008 21:01:12 +0000 Subject: Initial commit of cloth modifier from branch rev 13453 --- source/blender/blenkernel/intern/cloth.c | 1441 ++++++++++++++++++++++++++++++ 1 file changed, 1441 insertions(+) create mode 100644 source/blender/blenkernel/intern/cloth.c (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c new file mode 100644 index 00000000000..f871a307325 --- /dev/null +++ b/source/blender/blenkernel/intern/cloth.c @@ -0,0 +1,1441 @@ +/* cloth.c +* +* +* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. The Blender +* Foundation also sells licenses for use in proprietary software under +* the Blender License. See http://www.blender.org/BL/ for information +* about this. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* +* The Original Code is Copyright (C) Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +/* types */ +#include "DNA_curve_types.h" +#include "DNA_object_types.h" +#include "DNA_object_force.h" +#include "DNA_cloth_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_lattice_types.h" +#include "DNA_scene_types.h" +#include "DNA_modifier_types.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_edgehash.h" +#include "BLI_linklist.h" + +#include "BKE_curve.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_global.h" +#include "BKE_key.h" +#include "BKE_mesh.h" +#include "BKE_object.h" +#include "BKE_cloth.h" +#include "BKE_modifier.h" +#include "BKE_utildefines.h" +#include "BKE_DerivedMesh.h" +#include "BIF_editdeform.h" +#include "BIF_editkey.h" +#include "DNA_screen_types.h" +#include "BSE_headerbuttons.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "mydevice.h" + +#include "BKE_pointcache.h" + +#ifdef _WIN32 +void tstart ( void ) +{} +void tend ( void ) +{ +} +double tval() +{ + return 0; +} +#else +#include + static struct timeval _tstart, _tend; + static struct timezone tz; + void tstart ( void ) +{ + gettimeofday ( &_tstart, &tz ); +} +void tend ( void ) +{ + gettimeofday ( &_tend,&tz ); +} +double tval() +{ + double t1, t2; + t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 ); + t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 ); + return t2-t1; +} +#endif + +/* Our available solvers. */ +// 255 is the magic reserved number, so NEVER try to put 255 solvers in here! +// 254 = MAX! +static CM_SOLVER_DEF solvers [] = +{ + { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free }, + // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free }, +}; + +/* ********** cloth engine ******* */ +/* Prototypes for internal functions. +*/ +static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); +static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); +int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ); + + +/****************************************************************************** +* +* External interface called by modifier.c clothModifier functions. +* +******************************************************************************/ +/** + * cloth_init - creates a new cloth simulation. + * + * 1. create object + * 2. fill object with standard values or with the GUI settings if given + */ +void cloth_init ( ClothModifierData *clmd ) +{ + /* Initialize our new data structure to reasonable values. */ + clmd->sim_parms->gravity [0] = 0.0; + clmd->sim_parms->gravity [1] = 0.0; + clmd->sim_parms->gravity [2] = -9.81; + clmd->sim_parms->structural = 30.0; + clmd->sim_parms->shear = 30.0; + clmd->sim_parms->bending = 1.0; + clmd->sim_parms->Cdis = 5.0; + clmd->sim_parms->Cvi = 1.0; + 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->solver_type = 0; + clmd->sim_parms->preroll = 0; + clmd->sim_parms->maxspringlen = 10; + clmd->sim_parms->firstframe = 1; + clmd->sim_parms->lastframe = 250; + clmd->sim_parms->vgroup_mass = 0; + clmd->sim_parms->lastcachedframe = 0; + clmd->sim_parms->editedframe = 0; + clmd->sim_parms->autoprotect = 25; + clmd->sim_parms->firstcachedframe = -1.0; + + clmd->coll_parms->self_friction = 5.0; + clmd->coll_parms->friction = 10.0; + clmd->coll_parms->loop_count = 3; + clmd->coll_parms->epsilon = 0.015f; + clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; + + /* These defaults are copied from softbody.c's + * softbody_calc_forces() function. + */ + clmd->sim_parms->eff_force_scale = 1000.0; + clmd->sim_parms->eff_wind_scale = 250.0; + + // also from softbodies + clmd->sim_parms->maxgoal = 1.0f; + clmd->sim_parms->mingoal = 0.0f; + clmd->sim_parms->defgoal = 0.0f; + clmd->sim_parms->goalspring = 100.0f; + clmd->sim_parms->goalfrict = 0.0f; +} + + +BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) +{ + unsigned int i = 0; + BVH *bvh=NULL; + Cloth *cloth = clmd->clothObject; + ClothVertex *verts = NULL; + + if(!clmd) + return NULL; + + cloth = clmd->clothObject; + + if(!cloth) + return NULL; + + verts = cloth->verts; + + bvh = MEM_callocN(sizeof(BVH), "BVH"); + if (bvh == NULL) + { + printf("bvh: Out of memory.\n"); + return NULL; + } + + // springs = cloth->springs; + // numsprings = cloth->numsprings; + + bvh->flags = 0; + bvh->leaf_tree = NULL; + bvh->leaf_root = NULL; + bvh->tree = NULL; + + bvh->epsilon = epsilon; + bvh->numfaces = cloth->numfaces; + bvh->mfaces = cloth->mfaces; + + 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" ); + + for(i = 0; i < bvh->numverts; i++) + { + VECCOPY(bvh->current_x[i].co, verts[i].tx); + VECCOPY(bvh->current_xold[i].co, verts[i].txold); + } + + bvh_build (bvh); + + return bvh; +} + +void bvh_update_from_cloth(ClothModifierData *clmd, int moving) +{ + unsigned int i = 0; + Cloth *cloth = clmd->clothObject; + BVH *bvh = cloth->tree; + ClothVertex *verts = cloth->verts; + + if(!bvh) + return; + + if(cloth->numverts!=bvh->numverts) + return; + + if(cloth->verts) + { + for(i = 0; i < bvh->numverts; i++) + { + VECCOPY(bvh->current_x[i].co, verts[i].tx); + VECCOPY(bvh->current_xold[i].co, verts[i].txold); + } + } + + bvh_update(bvh, moving); +} + +// unused in the moment, cloth needs quads from mesh +DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) +{ + DerivedMesh *result = NULL; + int i; + int numverts = dm->getNumVerts ( dm ); + int numedges = dm->getNumEdges ( dm ); + int numfaces = dm->getNumFaces ( dm ); + + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); + + MVert *mvert2; + MFace *mface2; + unsigned int numtris=0; + unsigned int numquads=0; + int a = 0; + int random = 0; + int firsttime = 0; + float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3]; + float mag1=0, mag2=0; + + for ( i = 0; i < numfaces; i++ ) + { + if ( mface[i].v4 ) + numquads++; + else + numtris++; + } + + result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads ); + + if ( !result ) + return NULL; + + // do verts + mvert2 = CDDM_get_verts ( result ); + for ( a=0; av1 = mface[a].v2; + mf->v2 = mface[a].v3; + mf->v3 = mface[a].v4; + } + else + { + mf->v1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + } + + mf->v4 = 0; + mf->flag |= ME_SMOOTH; + + test_index_face ( mf, NULL, 0, 3 ); + + if ( mface[a].v4 ) + { + MFace *mf2; + + i++; + + mf2 = &mface2[i]; + /* + DM_copy_face_data(dm, result, a, i, 1); + + *mf2 = *inMF; + */ + + if ( random==1 ) + { + mf2->v1 = mface[a].v1; + mf2->v2 = mface[a].v2; + mf2->v3 = mface[a].v4; + } + else + { + mf2->v1 = mface[a].v4; + mf2->v2 = mface[a].v1; + mf2->v3 = mface[a].v3; + } + mf2->v4 = 0; + mf2->flag |= ME_SMOOTH; + + test_index_face ( mf2, NULL, 0, 3 ); + } + + i++; + } + + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); + + return result; + +} + + +DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) +{ + DerivedMesh *result = NULL; + unsigned int i = 0, a = 0, j=0; + int numverts = dm->getNumVerts ( dm ); + int numedges = dm->getNumEdges ( dm ); + int numfaces = dm->getNumFaces ( dm ); + + MVert *mvert = CDDM_get_verts ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); + + MVert *mvert2; + MFace *mface2; + unsigned int numtris=0; + unsigned int numquads=0; + EdgeHash *edgehash = NULL; + Cloth *cloth = clmd->clothObject; + ClothSpring *springs = cloth->springs; + unsigned int numsprings = cloth->numsprings; + + // create spring tearing hash + edgehash = BLI_edgehash_new(); + + for ( i = 0; i < numsprings; i++ ) + { + if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE ) + && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) + { + BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL ); + BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL ); + j++; + } + } + + // printf("found %d tears\n", j); + + result = CDDM_from_template ( dm, numverts, 0, numfaces ); + + if ( !result ) + return NULL; + + // do verts + mvert2 = CDDM_get_verts ( result ); + for ( a=0; av1 = mface[a].v1; + mf->v2 = mface[a].v2; + mf->v3 = mface[a].v3; + mf->v4 = mface[a].v4; + + test_index_face ( mf, NULL, 0, 4 ); + + i++; + } + } + + CDDM_lower_num_faces ( result, i ); + CDDM_calc_edges ( result ); + CDDM_calc_normals ( result ); + + BLI_edgehash_free ( edgehash, NULL ); + + return result; +} + +int modifiers_indexInObject(Object *ob, ModifierData *md_seek); + +int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + FILE *fp = NULL; + int stack_index = -1; + unsigned int a, ret = 1; + Cloth *cloth = clmd->clothObject; + + if(!cloth) + return 0; + + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index); + if(!fp) + ret = 0; + else { + for(a = 0; a < cloth->numverts; a++) + { + if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3) + { + ret = 0; + break; + } + if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3) + { + ret = 0; + break; + } + if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3) + { + ret = 0; + break; + } + } + + fclose(fp); + + if(clmd->sim_parms->lastcachedframe < framenr) + { + if(G.rt > 0) + printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe); + } + } + + if(G.rt > 0) + printf("cloth_read_cache: %f\n", framenr); + + return ret; +} + +void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + int stack_index = -1; + + // don't do anything as long as we're in editmode! + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) + { + /* delete cache free request */ + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + + return; + } + + /* clear cache if specific frame cleaning requested or cache is not protected */ + if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE)) + { + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); + + /* update last cached frame # */ + clmd->sim_parms->lastcachedframe = framenr; + + /* update first cached frame # */ + if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0)) + clmd->sim_parms->firstcachedframe = -1.0; + + if(G.rt > 0) + printf("cloth_clear_cache: %f\n", framenr); + } + + /* delete cache free request */ + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + + +} +void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) +{ + FILE *fp = NULL; + int stack_index = -1; + unsigned int a; + Cloth *cloth = clmd->clothObject; + + if(G.rt > 0) + printf("cloth_write_cache: %f\n", framenr); + + if(!cloth) + { + if(G.rt > 0) + printf("cloth_write_cache: no cloth\n"); + return; + } + + stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); + if(!fp) + { + if(G.rt > 0) + printf("cloth_write_cache: no fp\n"); + return; + } + + for(a = 0; a < cloth->numverts; a++) + { + fwrite(&cloth->verts[a].x, sizeof(float),3,fp); + fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp); + fwrite(&cloth->verts[a].v, sizeof(float),3,fp); + } + + /* update last cached frame # */ + clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr); + + /* update first cached frame # */ + if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0))) + clmd->sim_parms->firstcachedframe = framenr; + + if(G.rt > 0) + printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr); + + fclose(fp); +} + + + +/************************************************ + * clothModifier_do - main simulation function +************************************************/ +DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) + +{ + unsigned int i; + Cloth *cloth = clmd->clothObject; + float framenr = G.scene->r.cfra; + float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); + ListBase *effectors = NULL; + ClothVertex *verts = NULL; + float deltaTime = current_time - clmd->sim_parms->sim_time; + unsigned int numverts = -1; + unsigned int numedges = -1; + unsigned int numfaces = -1; + MVert *mvert = NULL; + MEdge *medge = NULL; + MFace *mface = NULL; + DerivedMesh *result = NULL; + + if(G.rt > 0) + printf("clothModifier_do start\n"); + + /* we're getting called two times during file load, + resulting in a not valid G.relbase on the first time (cache makes problems) + --> just return back */ + if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED)&& (!G.relbase_valid)) + { + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED; + return dm; + } + + result = CDDM_copy(dm); + + if(!result) + { + return dm; + } + + numverts = result->getNumVerts(result); + numedges = result->getNumEdges(result); + numfaces = result->getNumFaces(result); + mvert = dm->getVertArray(result); + medge = dm->getEdgeArray(result); + mface = dm->getFaceArray(result); + + /* check if cache is active / if file is already saved */ + /* + if ((!G.relbase_valid) && ( deltaTime != 1.0f )) + { + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; +} + */ + + if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) + { + cloth_free_modifier (ob, clmd); + if(G.rt > 0) + printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n"); + } + + // unused in the moment, calculated seperately in implicit.c + clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; + + if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) ) + { + /* only force free the cache if we have a different number of verts */ + if(clmd->clothObject && (numverts != clmd->clothObject->numverts )) + { + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; + cloth_free_modifier ( ob, clmd ); + } + + cloth_clear_cache(ob, clmd, 0); + + if ( !cloth_from_object ( ob, clmd, result, framenr ) ) + return result; + + if ( clmd->clothObject == NULL ) + return result; + + cloth = clmd->clothObject; + + if(!cloth_read_cache(ob, clmd, framenr)) + { + /* save first frame in case we have a reseted object + and we move one frame forward. + In that case we would only start with the SECOND frame + if we don't save the current state before + TODO PROBLEM: IMHO we can't track external movement from the + first frame in this case! */ + /* + if ( deltaTime == 1.0f ) + cloth_write_cache(ob, clmd, framenr-1.0); + */ + if(G.rt > 0) + printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n"); + } + else + { + if(G.rt > 0) + printf("cloth_from_object cloth_read_cache\n"); + + implicit_set_positions(clmd); + } + + clmd->sim_parms->sim_time = current_time; + } + + // only be active during a specific period: + // that's "first frame" and "last frame" on GUI + + // TODO: enable later again after refactoring + if ( current_time < clmd->sim_parms->firstframe ) + { + return result; + } + else if ( current_time > clmd->sim_parms->lastframe ) + { + int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + + if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) + { + if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe)) + { + implicit_set_positions(clmd); + + // Copy the result back to the object. + cloth_to_object (ob, clmd, result); + } + } + return result; + } + + /* 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"); + + if(!cloth_read_cache(ob, clmd, framenr)) + { + verts = cloth->verts; + + // Force any pinned verts to their constrained location. + for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) + { + // Save the previous position. + VECCOPY ( verts->xold, verts->xconst ); + VECCOPY ( verts->txold, verts->x ); + + // Get the current position. + VECCOPY ( verts->xconst, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->xconst ); + } + + tstart(); + + // Call the solver. + if ( solvers [clmd->sim_parms->solver_type].solver ) + solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); + + tend(); + // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); + + cloth_write_cache(ob, clmd, framenr); + + // check for autoprotection + if(framenr >= clmd->sim_parms->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(G.rt > 0) + printf("clothModifier_do deltaTime=1 cachewrite\n"); + } + else + { + if(G.rt > 0) + printf("clothModifier_do deltaTime=1 cacheread\n"); + implicit_set_positions(clmd); + } + + // Copy the result back to the object. + cloth_to_object (ob, clmd, result); + } + else if(deltaTime == 0.0f) + { + if(G.rt > 0) + printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); + if(cloth_read_cache(ob, clmd, framenr)) + { + cloth_to_object (ob, clmd, result); + implicit_set_positions(clmd); + } + 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); + } + } + else + { + if(G.rt > 0) + printf("clothModifier_do deltaTime!=1 clmd->clothObject != NULL\n"); + 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; + } + } + + return result; +} + +/* frees all */ +void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) +{ + Cloth *cloth = NULL; + + if ( !clmd ) + return; + + cloth = clmd->clothObject; + + + if ( cloth ) + { + // If our solver provides a free function, call it + if ( solvers [clmd->sim_parms->solver_type].free ) + { + solvers [clmd->sim_parms->solver_type].free ( clmd ); + } + + // Free the verts. + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + + cloth->verts = NULL; + cloth->numverts = 0; + + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + + cloth->springs = NULL; + cloth->numsprings = 0; + + // free BVH collision tree + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + + // we save our faces for collision objects + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); + /* + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + */ + MEM_freeN ( cloth ); + clmd->clothObject = NULL; + } + clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET; +} + +/* frees all */ +void cloth_free_modifier_extern ( ClothModifierData *clmd ) +{ + Cloth *cloth = NULL; + if(G.rt > 0) + printf("cloth_free_modifier_extern\n"); + + if ( !clmd ) + return; + + cloth = clmd->clothObject; + + if ( cloth ) + { + if(G.rt > 0) + printf("cloth_free_modifier_extern in\n"); + + // If our solver provides a free function, call it + if ( solvers [clmd->sim_parms->solver_type].free ) + { + solvers [clmd->sim_parms->solver_type].free ( clmd ); + } + + // Free the verts. + if ( cloth->verts != NULL ) + MEM_freeN ( cloth->verts ); + + cloth->verts = NULL; + cloth->numverts = 0; + + // Free the springs. + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + + cloth->springs = NULL; + cloth->numsprings = 0; + + // free BVH collision tree + if ( cloth->tree ) + bvh_free ( ( BVH * ) cloth->tree ); + + // we save our faces for collision objects + if ( cloth->mfaces ) + MEM_freeN ( cloth->mfaces ); + /* + if(clmd->clothObject->facemarks) + MEM_freeN(clmd->clothObject->facemarks); + */ + MEM_freeN ( cloth ); + clmd->clothObject = NULL; + } +} + +/****************************************************************************** +* +* Internal functions. +* +******************************************************************************/ + +/** + * cloth_to_object - copies the deformed vertices to the object. + * + **/ +static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm) +{ + unsigned int i = 0; + MVert *mvert = NULL; + unsigned int numverts; + Cloth *cloth = clmd->clothObject; + + if (clmd->clothObject) { + /* inverse matrix is not uptodate... */ + Mat4Invert (ob->imat, ob->obmat); + + mvert = CDDM_get_verts(dm); + numverts = dm->getNumVerts(dm); + + for (i = 0; i < numverts; i++) + { + VECCOPY (mvert[i].co, cloth->verts[i].x); + Mat4MulVecfl (ob->imat, mvert[i].co); /* cloth is in global coords */ + } + } +} + + +/** + * cloth_apply_vgroup - applies a vertex group as specified by type + * + **/ +/* can be optimized to do all groups in one loop */ +static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) +{ + unsigned int i = 0; + unsigned int j = 0; + MDeformVert *dvert = NULL; + Cloth *clothObj = NULL; + unsigned int numverts = dm->getNumVerts ( dm ); + float goalfac = 0; + ClothVertex *verts = NULL; + // clmd->sim_parms->vgroup_mass + + clothObj = clmd->clothObject; + + if ( !dm ) + return; + + numverts = dm->getNumVerts ( dm ); + + verts = clothObj->verts; + + if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || + (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && + ((clmd->sim_parms->vgroup_mass>0) || + (clmd->sim_parms->vgroup_struct>0)|| + (clmd->sim_parms->vgroup_bend>0))) + { + for ( i = 0; i < numverts; i++, verts++ ) + { + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); + if ( dvert ) + { + for ( j = 0; j < dvert->totweight; j++ ) + { + if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) + { + verts->goal = dvert->dw [j].weight; + goalfac= 1.0f; + + /* + // Kicking goal factor to simplify things...who uses that anyway? + // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal ); + */ + + verts->goal = ( float ) pow ( verts->goal , 4.0f ); + if ( verts->goal >=SOFTGOALSNAP ) + verts->flags |= CLOTH_VERT_FLAG_PINNED; + } + + if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) + { + if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1)) + { + verts->struct_stiff = dvert->dw [j].weight; + verts->shear_stiff = dvert->dw [j].weight; + } + + if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend-1)) + { + verts->bend_stiff = dvert->dw [j].weight; + } + } + } + } + } + } +} + +/* +helper function to get proper spring length +when object is rescaled +*/ +float cloth_globallen ( float *v1,float *v2,Object *ob ) +{ + float p1[3],p2[3]; + VECCOPY ( p1,v1 ); + Mat4MulVecfl ( ob->obmat, p1 ); + VECCOPY ( p2,v2 ); + Mat4MulVecfl ( ob->obmat, p2 ); + return VecLenf ( p1,p2 ); +} + +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr) +{ + unsigned int i = 0; + MVert *mvert = NULL; + ClothVertex *verts = NULL; + float tnull[3] = {0,0,0}; + int cache_there = 0; + + // If we have a clothObject, free it. + if ( clmd->clothObject != NULL ) + { + cloth_free_modifier ( ob, clmd ); + if(G.rt > 0) + printf("cloth_free_modifier cloth_from_object\n"); + } + + // Allocate a new cloth object. + clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" ); + if ( clmd->clothObject ) + { + clmd->clothObject->old_solver_type = 255; + // clmd->clothObject->old_collision_type = 255; + } + else if ( !clmd->clothObject ) + { + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." ); + return 0; + } + + // mesh input objects need DerivedMesh + if ( !dm ) + return 0; + + cloth_from_mesh ( ob, clmd, dm ); + + if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe)))) + { + // no cache there + cache_there = 0; + if(G.rt > 0) + printf("cache_there = 0\n"); + } + else + { + // we have a cache + cache_there = 1; + if(G.rt > 0) + printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe); + } + + // create springs + clmd->clothObject->springs = NULL; + clmd->clothObject->numsprings = -1; + + mvert = dm->getVertArray ( dm ); + verts = clmd->clothObject->verts; + + // set initial values + for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) + { + if(!cache_there) + { + VECCOPY ( verts->x, mvert[i].co ); + Mat4MulVecfl ( ob->obmat, verts->x ); + } + + verts->mass = clmd->sim_parms->mass; + + if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) + verts->goal= clmd->sim_parms->defgoal; + else + verts->goal= 0.0f; + + verts->flags = 0; + VECCOPY ( verts->xold, verts->x ); + VECCOPY ( verts->xconst, verts->x ); + VECCOPY ( verts->txold, verts->x ); + VecMulf ( verts->v, 0.0f ); + + verts->impulse_count = 0; + VECCOPY ( verts->impulse, tnull ); + } + + // apply / set vertex groups + // has to be happen before springs are build! + cloth_apply_vgroup (clmd, dm); + + if ( !cloth_build_springs ( clmd, dm ) ) + { + cloth_free_modifier ( ob, clmd ); + modifier_setError ( & ( clmd->modifier ), "Can't build springs." ); + printf("cloth_free_modifier cloth_build_springs\n"); + return 0; + } + + // init our solver + if ( solvers [clmd->sim_parms->solver_type].init ) + solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + + clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + + return 1; +} + + +static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ) +{ + unsigned int numverts = dm->getNumVerts ( dm ); + unsigned int numfaces = dm->getNumFaces ( dm ); + MFace *mface = CDDM_get_faces(dm); + unsigned int i = 0; + + /* Allocate our vertices. + */ + clmd->clothObject->numverts = numverts; + clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); + if ( clmd->clothObject->verts == NULL ) + { + cloth_free_modifier ( ob, clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." ); + printf("cloth_free_modifier clmd->clothObject->verts\n"); + return; + } + + // save face information + clmd->clothObject->numfaces = numfaces; + clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" ); + if ( clmd->clothObject->mfaces == NULL ) + { + cloth_free_modifier ( ob, clmd ); + modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." ); + printf("cloth_free_modifier clmd->clothObject->mfaces\n"); + return; + } + for ( i = 0; i < numfaces; i++ ) + memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) ); + + /* Free the springs since they can't be correct if the vertices + * changed. + */ + if ( clmd->clothObject->springs != NULL ) + MEM_freeN ( clmd->clothObject->springs ); + +} + +/*************************************************************************************** +* SPRING NETWORK BUILDING IMPLEMENTATION BEGIN +***************************************************************************************/ + +// be carefull: implicit solver has to be resettet when using this one! +// --> only for implicit handling of this spring! +int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type) +{ + Cloth *cloth = clmd->clothObject; + ClothSpring *spring = NULL; + + if(cloth) + { + // TODO: look if this spring is already there + + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + spring->ij = indexA; + spring->kl = indexB; + spring->restlen = restlength; + spring->type = spring_type; + spring->flags = 0; + + cloth->numsprings++; + + BLI_linklist_append ( &cloth->springs, spring ); + + return 1; + } + return 0; +} + +int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) +{ + Cloth *cloth = clmd->clothObject; + ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL; + unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0; + unsigned int i = 0; + unsigned int numverts = dm->getNumVerts ( dm ); + unsigned int numedges = dm->getNumEdges ( dm ); + unsigned int numfaces = dm->getNumFaces ( dm ); + MEdge *medge = CDDM_get_edges ( dm ); + MFace *mface = CDDM_get_faces ( dm ); + unsigned int index2 = 0; // our second vertex index + LinkNode **edgelist = NULL; + EdgeHash *edgehash = NULL; + LinkNode *search = NULL, *search2 = NULL; + float temp[3]; + LinkNode *node = NULL, *node2 = NULL; + + // error handling + if ( numedges==0 ) + return 0; + + cloth->springs = NULL; + + edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" ); + for ( i = 0; i < numverts; i++ ) + { + edgelist[i] = NULL; + } + + if ( cloth->springs ) + MEM_freeN ( cloth->springs ); + + // create spring network hash + edgehash = BLI_edgehash_new(); + + // structural springs + for ( i = 0; i < numedges; i++ ) + { + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if ( spring ) + { + spring->ij = medge[i].v1; + spring->kl = medge[i].v2; + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + /* + if(spring->restlen > 1.0) + { + printf("i: %d, L: %f\n", i, spring->restlen); + printf("%d, x: %f, y: %f, z: %f\n", cloth->verts[spring->ij].x[0], cloth->verts[spring->ij].x[1], spring->ij, cloth->verts[spring->ij].x[2]); + printf("%d, x: %f, y: %f, z: %f\n\n",spring->kl, cloth->verts[spring->kl].x[0], cloth->verts[spring->kl].x[1], cloth->verts[spring->kl].x[2]); + } + */ + clmd->coll_parms->avg_spring_len += spring->restlen; + spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; + spring->flags = 0; + spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0; + struct_springs++; + + if(!i) + node2 = BLI_linklist_append_fast ( &cloth->springs, spring ); + else + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; + } + } + + clmd->coll_parms->avg_spring_len /= struct_springs; + + // shear springs + for ( i = 0; i < numfaces; i++ ) + { + spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + spring->ij = mface[i].v1; + spring->kl = mface[i].v3; + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; + spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; + + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; + + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; + + if ( mface[i].v4 ) + { + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + spring->ij = mface[i].v2; + spring->kl = mface[i].v4; + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; + spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; + + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; + + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; + } + } + + // bending springs + search2 = cloth->springs; + for ( i = struct_springs; i < struct_springs+shear_springs; i++ ) + { + if ( !search2 ) + break; + + tspring2 = search2->link; + search = edgelist[tspring2->kl]; + while ( search ) + { + tspring = search->link; + index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) ); + + // check for existing spring + // check also if startpoint is equal to endpoint + if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij ) + && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) + && ( index2!=tspring2->ij ) ) + { + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + spring->ij = tspring2->ij; + spring->kl = index2; + VECSUB ( temp, cloth->verts[index2].x, cloth->verts[tspring2->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_BENDING; + spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; + BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); + bend_springs++; + + node2 = BLI_linklist_append_fast ( &node->next, spring ); + node = node2; + } + search = search->next; + } + search2 = search2->next; + } + + cloth->numsprings = struct_springs + shear_springs + bend_springs; + + for ( i = 0; i < numverts; i++ ) + { + BLI_linklist_free ( edgelist[i],NULL ); + } + if ( edgelist ) + MEM_freeN ( edgelist ); + + BLI_edgehash_free ( edgehash, NULL ); + + return 1; + +} /* cloth_build_springs */ +/*************************************************************************************** +* SPRING NETWORK BUILDING IMPLEMENTATION END +***************************************************************************************/ + -- cgit v1.2.3 From 7a7a52226f52952534c93832c3e7b0492ec0ad30 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 29 Jan 2008 23:13:31 +0000 Subject: makes bullet independant from gameengine for cmake, introduces esc-key during sim, disables collisions when no bullet there --- source/blender/blenkernel/intern/cloth.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f871a307325..dac77381175 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -639,6 +639,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d MEdge *medge = NULL; MFace *mface = NULL; DerivedMesh *result = NULL; + int ret = 0; if(G.rt > 0) printf("clothModifier_do start\n"); @@ -782,12 +783,17 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // Call the solver. if ( solvers [clmd->sim_parms->solver_type].solver ) - solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); + { + ret = solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); + } tend(); // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); - - cloth_write_cache(ob, clmd, framenr); + + if(ret) + cloth_write_cache(ob, clmd, framenr); + else + clmd->sim_parms->sim_time--; // check for autoprotection if(framenr >= clmd->sim_parms->autoprotect) -- cgit v1.2.3 From 4ed28a99a70fdceb85e8e4f6972fc632cf192d79 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 30 Jan 2008 02:05:37 +0000 Subject: Cloth: Bugfix: 1. Kicking esc again, 2. Collision modifier needed to be updated when going backward in time, 3. GUI change when no bullet there --- source/blender/blenkernel/intern/cloth.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index dac77381175..ace5f37b7a4 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -526,6 +526,9 @@ int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) if(G.rt > 0) printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe); } + + if(G.rt > 0) + printf("cloth_read_cache: %f successfully \n", framenr); } if(G.rt > 0) @@ -647,7 +650,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d /* we're getting called two times during file load, resulting in a not valid G.relbase on the first time (cache makes problems) --> just return back */ - if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED)&& (!G.relbase_valid)) + if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED) && (!G.relbase_valid)) { clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED; return dm; @@ -732,8 +735,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // only be active during a specific period: // that's "first frame" and "last frame" on GUI - - // TODO: enable later again after refactoring if ( current_time < clmd->sim_parms->firstframe ) { return result; -- cgit v1.2.3 From 0e7bdb959eb694d384a1938d1f580365043c0ed6 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 3 Feb 2008 22:37:43 +0000 Subject: Cloth: Fixed: [#8210] (includes bad spring calculation), only mesh can get cloth assigned, New: initial try of Bridson/Fedkiw friction formula implementation, better GUI feedback when e.g. cache is protected and settings too --- source/blender/blenkernel/intern/cloth.c | 64 ++++++++++++++------------------ 1 file changed, 27 insertions(+), 37 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ace5f37b7a4..e27df5b1ba1 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -166,7 +166,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->firstcachedframe = -1.0; clmd->coll_parms->self_friction = 5.0; - clmd->coll_parms->friction = 10.0; + clmd->coll_parms->friction = 5.0; clmd->coll_parms->loop_count = 3; clmd->coll_parms->epsilon = 0.015f; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; @@ -689,7 +689,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) ) - { + { /* only force free the cache if we have a different number of verts */ if(clmd->clothObject && (numverts != clmd->clothObject->numverts )) { @@ -756,6 +756,16 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d return result; } + // check for autoprotection + if(framenr >= clmd->sim_parms->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(G.rt > 0) + printf("clothModifier_do deltaTime=1 cachewrite\n"); + /* nice moving one frame forward */ if ( deltaTime == 1.0f ) { @@ -795,16 +805,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d cloth_write_cache(ob, clmd, framenr); else clmd->sim_parms->sim_time--; - - // check for autoprotection - if(framenr >= clmd->sim_parms->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(G.rt > 0) - printf("clothModifier_do deltaTime=1 cachewrite\n"); } else { @@ -1041,14 +1041,16 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts = clothObj->verts; - if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || + if ((((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && ((clmd->sim_parms->vgroup_mass>0) || (clmd->sim_parms->vgroup_struct>0)|| - (clmd->sim_parms->vgroup_bend>0))) + (clmd->sim_parms->vgroup_bend>0)))|| (clmd->sim_parms->vgroup_mass>0)) { for ( i = 0; i < numverts; i++, verts++ ) { + verts->mass = 1.0; // standard mass + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { @@ -1082,26 +1084,17 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts->bend_stiff = dvert->dw [j].weight; } } + + if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) + { + verts->mass = dvert->dw [j].weight; + } } } } } } -/* -helper function to get proper spring length -when object is rescaled -*/ -float cloth_globallen ( float *v1,float *v2,Object *ob ) -{ - float p1[3],p2[3]; - VECCOPY ( p1,v1 ); - Mat4MulVecfl ( ob->obmat, p1 ); - VECCOPY ( p2,v2 ); - Mat4MulVecfl ( ob->obmat, p2 ); - return VecLenf ( p1,p2 ); -} - static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr) { unsigned int i = 0; @@ -1189,6 +1182,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // has to be happen before springs are build! cloth_apply_vgroup (clmd, dm); + if ( !cloth_build_springs ( clmd, dm ) ) { cloth_free_modifier ( ob, clmd ); @@ -1197,12 +1191,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d return 0; } + // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); - + return 1; } @@ -1326,14 +1321,6 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->kl = medge[i].v2; VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); - /* - if(spring->restlen > 1.0) - { - printf("i: %d, L: %f\n", i, spring->restlen); - printf("%d, x: %f, y: %f, z: %f\n", cloth->verts[spring->ij].x[0], cloth->verts[spring->ij].x[1], spring->ij, cloth->verts[spring->ij].x[2]); - printf("%d, x: %f, y: %f, z: %f\n\n",spring->kl, cloth->verts[spring->kl].x[0], cloth->verts[spring->kl].x[1], cloth->verts[spring->kl].x[2]); - } - */ clmd->coll_parms->avg_spring_len += spring->restlen; spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; @@ -1438,6 +1425,9 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) MEM_freeN ( edgelist ); BLI_edgehash_free ( edgehash, NULL ); + + if(G.rt>0) + printf("avg_len: %f\n",clmd->coll_parms->avg_spring_len); return 1; -- cgit v1.2.3 From a8c25e279d2209665cf7f561c4cb32837dc83aa3 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 5 Feb 2008 15:09:48 +0000 Subject: Cloth: Fix for crash with meshes with no faces, 2. Fix for crash on switching from to another mesh --- source/blender/blenkernel/intern/cloth.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e27df5b1ba1..5d0601959cc 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -51,6 +51,7 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" +#include "BLI_editVert.h" #include "BLI_edgehash.h" #include "BLI_linklist.h" @@ -203,6 +204,10 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) verts = cloth->verts; + // in the moment, return zero if no faces there + if(!cloth->numfaces) + return NULL; + bvh = MEM_callocN(sizeof(BVH), "BVH"); if (bvh == NULL) { -- cgit v1.2.3 From eb281bff39d255011e82ae8cbf8129eed811d7ec Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 6 Feb 2008 22:59:56 +0000 Subject: Cloth: 1. fix problem with pinning (reported by ZanQdo), 2. fix cache protected + 'not saved' gui message bug (reported by Tobias Regenbrecht) --- source/blender/blenkernel/intern/cloth.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 5d0601959cc..07a32771fef 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -761,8 +761,8 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d return result; } - // check for autoprotection - if(framenr >= clmd->sim_parms->autoprotect) + // check for autoprotection, but only if cache active + if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid)) { if(G.rt > 0) printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect); @@ -1073,7 +1073,9 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts->goal = ( float ) pow ( verts->goal , 4.0f ); if ( verts->goal >=SOFTGOALSNAP ) - verts->flags |= CLOTH_VERT_FLAG_PINNED; + { + verts->flags |= CLOTH_VERT_FLAG_PINNED; + } } if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) @@ -1089,11 +1091,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts->bend_stiff = dvert->dw [j].weight; } } - - if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) + /* + // for later + if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1)) { verts->mass = dvert->dw [j].weight; } + */ } } } -- cgit v1.2.3 From 1efba5bdb15ab4782d41b418a4927f1bb696bfb7 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Fri, 8 Feb 2008 00:55:48 +0000 Subject: Cloth: Hopefully fixed bug reported from bjornmose (2nd try) --- source/blender/blenkernel/intern/cloth.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 07a32771fef..d75c4ecbfac 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -182,8 +182,8 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->maxgoal = 1.0f; clmd->sim_parms->mingoal = 0.0f; clmd->sim_parms->defgoal = 0.0f; - clmd->sim_parms->goalspring = 100.0f; - clmd->sim_parms->goalfrict = 0.0f; + clmd->sim_parms->goalspring = 10.0f; + clmd->sim_parms->goalfrict = 5.0f; } @@ -1035,7 +1035,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) unsigned int numverts = dm->getNumVerts ( dm ); float goalfac = 0; ClothVertex *verts = NULL; - // clmd->sim_parms->vgroup_mass clothObj = clmd->clothObject; @@ -1111,6 +1110,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; int cache_there = 0; + Cloth *cloth = NULL; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) @@ -1126,6 +1126,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d { clmd->clothObject->old_solver_type = 255; // clmd->clothObject->old_collision_type = 255; + cloth = clmd->clothObject; } else if ( !clmd->clothObject ) { @@ -1200,6 +1201,13 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d return 0; } + for ( i = 0; i < dm->getNumVerts(dm); i++) + { + if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO)) + { + cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL); + } + } // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) @@ -1273,10 +1281,11 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in spring->restlen = restlength; spring->type = spring_type; spring->flags = 0; + spring->stiffness = 0; cloth->numsprings++; - BLI_linklist_append ( &cloth->springs, spring ); + BLI_linklist_prepend ( &cloth->springs, spring ); return 1; } -- cgit v1.2.3 From 69e6a6cbc9cfdae6804d538cb4810672c5318d48 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 11 Feb 2008 13:30:52 +0000 Subject: Pointcache: Fixed non-availability when blend file was loaded from command line and also another case where you startet from an unsaved blend and switched to a saved one; Cloth: Fixid mass init, little speedup for collisions; Collision Modifier: More generalized it --- source/blender/blenkernel/intern/cloth.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d75c4ecbfac..407a7cfd8be 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -171,6 +171,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->coll_parms->loop_count = 3; clmd->coll_parms->epsilon = 0.015f; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; + clmd->coll_parms->collision_list = NULL; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. @@ -698,6 +699,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d /* only force free the cache if we have a different number of verts */ if(clmd->clothObject && (numverts != clmd->clothObject->numverts )) { + if(G.rt > 0) + printf("Force Freeing: numverts != clmd->clothObject->numverts\n"); + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; cloth_free_modifier ( ob, clmd ); } @@ -742,12 +746,17 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d // that's "first frame" and "last frame" on GUI if ( current_time < clmd->sim_parms->firstframe ) { + if(G.rt > 0) + printf("current_time < clmd->sim_parms->firstframe\n"); return result; } else if ( current_time > clmd->sim_parms->lastframe ) { int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); + if(G.rt > 0) + printf("current_time > clmd->sim_parms->lastframe\n"); + if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) { if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe)) @@ -1171,7 +1180,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d Mat4MulVecfl ( ob->obmat, verts->x ); } - verts->mass = clmd->sim_parms->mass; + /* no GUI interface yet */ + verts->mass = clmd->sim_parms->mass = 1.0f; if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) verts->goal= clmd->sim_parms->defgoal; -- cgit v1.2.3 From bb715a93b962c4f1f25d54fd6e9a8e435a172f73 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 11 Feb 2008 20:40:22 +0000 Subject: Cloth: 1. Speedup of collisions (up to 50%, see new dancing ballerina stats here: http://www.dldw.de/tmp/index.php?file=i_cloth-kdop-dancingb.jpg ; 2. changed vertex paint reset behaviour to only reset cloth if vertex group is really used --- source/blender/blenkernel/intern/cloth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 407a7cfd8be..e1e80a62d4c 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1054,11 +1054,11 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) verts = clothObj->verts; - if ((((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || + if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && ((clmd->sim_parms->vgroup_mass>0) || (clmd->sim_parms->vgroup_struct>0)|| - (clmd->sim_parms->vgroup_bend>0)))|| (clmd->sim_parms->vgroup_mass>0)) + (clmd->sim_parms->vgroup_bend>0))) { for ( i = 0; i < numverts; i++, verts++ ) { -- cgit v1.2.3 From e82484b0bb628a533fc1cd43be804c365d54f3f1 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 12 Feb 2008 11:04:58 +0000 Subject: Cloth: New: *simple* (OpenMP enabled) Selfcollisions available --- source/blender/blenkernel/intern/cloth.c | 158 ++++++------------------------- 1 file changed, 28 insertions(+), 130 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index e1e80a62d4c..ecd478be8fd 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -165,6 +165,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->editedframe = 0; clmd->sim_parms->autoprotect = 25; clmd->sim_parms->firstcachedframe = -1.0; + clmd->sim_parms->avg_spring_len = 0.0; clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 5.0; @@ -172,6 +173,8 @@ void cloth_init ( ClothModifierData *clmd ) clmd->coll_parms->epsilon = 0.015f; clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED; clmd->coll_parms->collision_list = NULL; + clmd->coll_parms->self_loop_count = 1.0; + clmd->coll_parms->selfepsilon = 0.75; /* These defaults are copied from softbody.c's * softbody_calc_forces() function. @@ -269,130 +272,6 @@ void bvh_update_from_cloth(ClothModifierData *clmd, int moving) bvh_update(bvh, moving); } -// unused in the moment, cloth needs quads from mesh -DerivedMesh *CDDM_convert_to_triangle ( DerivedMesh *dm ) -{ - DerivedMesh *result = NULL; - int i; - int numverts = dm->getNumVerts ( dm ); - int numedges = dm->getNumEdges ( dm ); - int numfaces = dm->getNumFaces ( dm ); - - MVert *mvert = CDDM_get_verts ( dm ); - MEdge *medge = CDDM_get_edges ( dm ); - MFace *mface = CDDM_get_faces ( dm ); - - MVert *mvert2; - MFace *mface2; - unsigned int numtris=0; - unsigned int numquads=0; - int a = 0; - int random = 0; - int firsttime = 0; - float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3]; - float mag1=0, mag2=0; - - for ( i = 0; i < numfaces; i++ ) - { - if ( mface[i].v4 ) - numquads++; - else - numtris++; - } - - result = CDDM_from_template ( dm, numverts, 0, numtris + 2*numquads ); - - if ( !result ) - return NULL; - - // do verts - mvert2 = CDDM_get_verts ( result ); - for ( a=0; av1 = mface[a].v2; - mf->v2 = mface[a].v3; - mf->v3 = mface[a].v4; - } - else - { - mf->v1 = mface[a].v1; - mf->v2 = mface[a].v2; - mf->v3 = mface[a].v3; - } - - mf->v4 = 0; - mf->flag |= ME_SMOOTH; - - test_index_face ( mf, NULL, 0, 3 ); - - if ( mface[a].v4 ) - { - MFace *mf2; - - i++; - - mf2 = &mface2[i]; - /* - DM_copy_face_data(dm, result, a, i, 1); - - *mf2 = *inMF; - */ - - if ( random==1 ) - { - mf2->v1 = mface[a].v1; - mf2->v2 = mface[a].v2; - mf2->v3 = mface[a].v4; - } - else - { - mf2->v1 = mface[a].v4; - mf2->v2 = mface[a].v1; - mf2->v3 = mface[a].v3; - } - mf2->v4 = 0; - mf2->flag |= ME_SMOOTH; - - test_index_face ( mf2, NULL, 0, 3 ); - } - - i++; - } - - CDDM_calc_edges ( result ); - CDDM_calc_normals ( result ); - - return result; - -} - - DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) { DerivedMesh *result = NULL; @@ -922,6 +801,11 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) // we save our faces for collision objects if ( cloth->mfaces ) MEM_freeN ( cloth->mfaces ); + + if(cloth->edgehash) + BLI_edgehash_free ( cloth->edgehash, NULL ); + + /* if(clmd->clothObject->facemarks) MEM_freeN(clmd->clothObject->facemarks); @@ -988,6 +872,11 @@ void cloth_free_modifier_extern ( ClothModifierData *clmd ) // we save our faces for collision objects if ( cloth->mfaces ) MEM_freeN ( cloth->mfaces ); + + if(cloth->edgehash) + BLI_edgehash_free ( cloth->edgehash, NULL ); + + /* if(clmd->clothObject->facemarks) MEM_freeN(clmd->clothObject->facemarks); @@ -1136,6 +1025,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d clmd->clothObject->old_solver_type = 255; // clmd->clothObject->old_collision_type = 255; cloth = clmd->clothObject; + clmd->clothObject->edgehash = NULL; } else if ( !clmd->clothObject ) { @@ -1236,8 +1126,7 @@ static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh * MFace *mface = CDDM_get_faces(dm); unsigned int i = 0; - /* Allocate our vertices. - */ + /* Allocate our vertices. */ clmd->clothObject->numverts = numverts; clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" ); if ( clmd->clothObject->verts == NULL ) @@ -1349,7 +1238,11 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->kl = medge[i].v2; VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); - clmd->coll_parms->avg_spring_len += spring->restlen; + clmd->sim_parms->avg_spring_len += spring->restlen; + cloth->verts[spring->ij].avg_spring_len += spring->restlen; + cloth->verts[spring->kl].avg_spring_len += spring->restlen; + cloth->verts[spring->ij].spring_count++; + cloth->verts[spring->kl].spring_count++; spring->type = CLOTH_SPRING_TYPE_STRUCTURAL; spring->flags = 0; spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0; @@ -1363,7 +1256,12 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) } } - clmd->coll_parms->avg_spring_len /= struct_springs; + clmd->sim_parms->avg_spring_len /= struct_springs; + + for(i = 0; i < numverts; i++) + { + cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49 / ((float)cloth->verts[i].spring_count); + } // shear springs for ( i = 0; i < numfaces; i++ ) @@ -1452,10 +1350,10 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) if ( edgelist ) MEM_freeN ( edgelist ); - BLI_edgehash_free ( edgehash, NULL ); + cloth->edgehash = edgehash; if(G.rt>0) - printf("avg_len: %f\n",clmd->coll_parms->avg_spring_len); + printf("avg_len: %f\n",clmd->sim_parms->avg_spring_len); return 1; -- cgit v1.2.3 From 31922633670f03ceb2e963984e418fecd1a59d40 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 13 Feb 2008 10:44:36 +0000 Subject: Cloth: changes in editmode will influence the velocity by 10% now, changed/add some update calls for the implicit function --- source/blender/blenkernel/intern/cloth.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ecd478be8fd..802e14b683f 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1112,6 +1112,9 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // init our solver if ( solvers [clmd->sim_parms->solver_type].init ) solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + + if(cache_there) + implicit_set_positions(clmd); clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); -- cgit v1.2.3 From e3e268253d5d4dc71ca530c744870b3b8ed710d9 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 20 Feb 2008 15:54:34 +0000 Subject: Cloth: Bugfix for wrong number of bending springs, could result in visual artifacts --- source/blender/blenkernel/intern/cloth.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 802e14b683f..ec128bc3a02 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1210,7 +1210,6 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) EdgeHash *edgehash = NULL; LinkNode *search = NULL, *search2 = NULL; float temp[3]; - LinkNode *node = NULL, *node2 = NULL; // error handling if ( numedges==0 ) @@ -1251,11 +1250,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0; struct_springs++; - if(!i) - node2 = BLI_linklist_append_fast ( &cloth->springs, spring ); - else - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_prepend ( &cloth->springs, spring ); } } @@ -1282,8 +1277,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_prepend ( &cloth->springs, spring ); if ( mface[i].v4 ) { @@ -1300,8 +1294,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_linklist_append ( &edgelist[spring->kl], spring ); shear_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_prepend ( &cloth->springs, spring ); } } @@ -1336,8 +1329,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); bend_springs++; - node2 = BLI_linklist_append_fast ( &node->next, spring ); - node = node2; + BLI_linklist_prepend ( &cloth->springs, spring ); } search = search->next; } -- cgit v1.2.3 From 824a714b470b4648b168410a61277bef5a50c81a Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 24 Feb 2008 11:16:37 +0000 Subject: Purge of compiler warnings... (hopefully everything still compiles, there are still more to remove) --- source/blender/blenkernel/intern/cloth.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ec128bc3a02..24def8211f1 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -277,20 +277,16 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) DerivedMesh *result = NULL; unsigned int i = 0, a = 0, j=0; int numverts = dm->getNumVerts ( dm ); - int numedges = dm->getNumEdges ( dm ); int numfaces = dm->getNumFaces ( dm ); MVert *mvert = CDDM_get_verts ( dm ); - MEdge *medge = CDDM_get_edges ( dm ); MFace *mface = CDDM_get_faces ( dm ); MVert *mvert2; MFace *mface2; - unsigned int numtris=0; - unsigned int numquads=0; EdgeHash *edgehash = NULL; Cloth *cloth = clmd->clothObject; - ClothSpring *springs = cloth->springs; + ClothSpring *springs = (ClothSpring *)cloth->springs; unsigned int numsprings = cloth->numsprings; // create spring tearing hash -- cgit v1.2.3 From e9ce2a9f3f7e93692a6dc1c25ed050391f510436 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 26 Feb 2008 09:55:07 +0000 Subject: Cloth: Little (bug)fix to let springs appear as an upper tridiagonal matrix --- source/blender/blenkernel/intern/cloth.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 24def8211f1..38b4cf6bcbb 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -23,9 +23,7 @@ * The Original Code is Copyright (C) Blender Foundation * All rights reserved. * -* The Original Code is: all of this file. -* -* Contributor(s): none yet. +* Contributor(s): Daniel Genrich * * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ @@ -501,8 +499,6 @@ void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) fclose(fp); } - - /************************************************ * clothModifier_do - main simulation function ************************************************/ @@ -1232,8 +1228,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) if ( spring ) { - spring->ij = medge[i].v1; - spring->kl = medge[i].v2; + spring->ij = MIN2(medge[i].v1, medge[i].v2); + spring->kl = MAX2(medge[i].v2, medge[i].v1); VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); clmd->sim_parms->avg_spring_len += spring->restlen; @@ -1262,8 +1258,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - spring->ij = mface[i].v1; - spring->kl = mface[i].v3; + spring->ij = MIN2(mface[i].v1, mface[i].v3); + spring->kl = MAX2(mface[i].v3, mface[i].v1); VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1279,8 +1275,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - spring->ij = mface[i].v2; - spring->kl = mface[i].v4; + spring->ij = MIN2(mface[i].v2, mface[i].v4); + spring->kl = MAX2(mface[i].v4, mface[i].v2); VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_SHEAR; @@ -1316,8 +1312,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - spring->ij = tspring2->ij; - spring->kl = index2; + spring->ij = MIN2(tspring2->ij, index2); + spring->kl = MAX2(tspring2->ij, index2); VECSUB ( temp, cloth->verts[index2].x, cloth->verts[tspring2->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; -- cgit v1.2.3 From f9fb9965aae0e2312329c04517f438718fd6a006 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 26 Feb 2008 14:25:29 +0000 Subject: Cloth: make cloth more crash resistant if memory allocation failed --- source/blender/blenkernel/intern/cloth.c | 91 ++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 5 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 38b4cf6bcbb..0e97a5fe9ef 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -234,6 +234,20 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) 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) + { + printf("bvh: Out of memory.\n"); + MEM_freeN(bvh); + return NULL; + } + + if (bvh->current_xold == NULL) + { + printf("bvh: Out of memory.\n"); + MEM_freeN(bvh); + return NULL; + } + for(i = 0; i < bvh->numverts; i++) { VECCOPY(bvh->current_x[i].co, verts[i].tx); @@ -1170,6 +1184,9 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + if(!spring) + return 0; + spring->ij = indexA; spring->kl = indexB; spring->restlen = restlength; @@ -1186,6 +1203,39 @@ int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned in return 0; } +void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist) +{ + unsigned int i = 0; + + if ( cloth->springs != NULL ) + { + LinkNode *search = cloth->springs; + while(search) + { + ClothSpring *spring = search->link; + + MEM_freeN ( spring ); + search = search->next; + } + BLI_linklist_free(cloth->springs, NULL); + + cloth->springs = NULL; + } + + if(edgelist) + { + for ( i = 0; i < cloth->numverts; i++ ) + { + BLI_linklist_free ( edgelist[i],NULL ); + } + + MEM_freeN ( edgelist ); + } + + if(cloth->edgehash) + BLI_edgehash_free ( cloth->edgehash, NULL ); +} + int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { Cloth *cloth = clmd->clothObject; @@ -1210,6 +1260,10 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) cloth->springs = NULL; edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" ); + + if(!edgelist) + return 0; + for ( i = 0; i < numverts; i++ ) { edgelist[i] = NULL; @@ -1244,9 +1298,15 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_linklist_prepend ( &cloth->springs, spring ); } + else + { + cloth_free_errorsprings(cloth, edgehash, edgelist); + return 0; + } } - clmd->sim_parms->avg_spring_len /= struct_springs; + if(struct_springs > 0) + clmd->sim_parms->avg_spring_len /= struct_springs; for(i = 0; i < numverts; i++) { @@ -1257,6 +1317,12 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) for ( i = 0; i < numfaces; i++ ) { spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if(!spring) + { + cloth_free_errorsprings(cloth, edgehash, edgelist); + return 0; + } spring->ij = MIN2(mface[i].v1, mface[i].v3); spring->kl = MAX2(mface[i].v3, mface[i].v1); @@ -1274,6 +1340,12 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) if ( mface[i].v4 ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if(!spring) + { + cloth_free_errorsprings(cloth, edgehash, edgelist); + return 0; + } spring->ij = MIN2(mface[i].v2, mface[i].v4); spring->kl = MAX2(mface[i].v4, mface[i].v2); @@ -1311,6 +1383,12 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) && ( index2!=tspring2->ij ) ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if(!spring) + { + cloth_free_errorsprings(cloth, edgehash, edgelist); + return 0; + } spring->ij = MIN2(tspring2->ij, index2); spring->kl = MAX2(tspring2->ij, index2); @@ -1330,12 +1408,15 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) cloth->numsprings = struct_springs + shear_springs + bend_springs; - for ( i = 0; i < numverts; i++ ) - { - BLI_linklist_free ( edgelist[i],NULL ); - } if ( edgelist ) + { + for ( i = 0; i < numverts; i++ ) + { + BLI_linklist_free ( edgelist[i],NULL ); + } + MEM_freeN ( edgelist ); + } cloth->edgehash = edgehash; -- cgit v1.2.3 From 7d310f4e5c9059a7e734d852424915e8aac7319e Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 27 Feb 2008 03:23:17 +0000 Subject: Cloth: fixed completely useless/wrong friction force; changed some initial settings --- source/blender/blenkernel/intern/cloth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 0e97a5fe9ef..b1849f8b693 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -184,7 +184,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->maxgoal = 1.0f; clmd->sim_parms->mingoal = 0.0f; clmd->sim_parms->defgoal = 0.0f; - clmd->sim_parms->goalspring = 10.0f; + clmd->sim_parms->goalspring = 1.0f; clmd->sim_parms->goalfrict = 5.0f; } -- cgit v1.2.3 From 905a2d374a9b418fe2d358f4c7fdbc12a6253f91 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 28 Feb 2008 00:01:19 +0000 Subject: 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 --- source/blender/blenkernel/intern/cloth.c | 56 ++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 21 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') 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; -- cgit v1.2.3 From 6169b29b3a53eca3e342aeee9d33809e61f026c3 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 28 Feb 2008 23:12:50 +0000 Subject: Cloth: Bugfix for wrong calculated bending springs, Bugfix for selfcollisions (faster + bugfix for explode), Changed: Collision response also put vertices back to surface now --- source/blender/blenkernel/intern/cloth.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d78a9f51f77..63982e4162a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -147,7 +147,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->structural = 30.0; clmd->sim_parms->shear = 30.0; clmd->sim_parms->bending = 1.0; - clmd->sim_parms->Cdis = 5.0; + clmd->sim_parms->Cdis = 1.0; // was 5 clmd->sim_parms->Cvi = 1.0; clmd->sim_parms->mass = 1.0f; clmd->sim_parms->stepsPerFrame = 5; @@ -186,7 +186,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->mingoal = 0.0f; clmd->sim_parms->defgoal = 0.0f; clmd->sim_parms->goalspring = 1.0f; - clmd->sim_parms->goalfrict = 5.0f; + clmd->sim_parms->goalfrict = 0.0f; } @@ -310,7 +310,7 @@ DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) for ( i = 0; i < numsprings; i++ ) { if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE ) - && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) + && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) { BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL ); BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL ); @@ -1392,9 +1392,8 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) // check for existing spring // check also if startpoint is equal to endpoint - if ( !BLI_edgehash_haskey ( edgehash, index2, tspring2->ij ) - && !BLI_edgehash_haskey ( edgehash, tspring2->ij, index2 ) - && ( index2!=tspring2->ij ) ) + if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) ) + && ( index2!=tspring2->ij ) ) { spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); @@ -1406,11 +1405,11 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(tspring2->ij, index2); spring->kl = MAX2(tspring2->ij, index2); - VECSUB ( temp, cloth->verts[index2].x, cloth->verts[tspring2->ij].x ); + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); spring->restlen = sqrt ( INPR ( temp, temp ) ); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; - BLI_edgehash_insert ( edgehash, spring->ij, index2, NULL ); + BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL ); bend_springs++; BLI_linklist_prepend ( &cloth->springs, spring ); @@ -1420,6 +1419,21 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) search2 = search2->next; } + /* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */ + for ( i = 0; i < numedges; i++ ) // struct springs + BLI_edgehash_insert ( edgehash, MIN2(medge[i].v1, medge[i].v2), MAX2(medge[i].v2, medge[i].v1), NULL ); + + for ( i = 0; i < numfaces; i++ ) // edge springs + { + BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL ); + + if(mface[i].v4) + { + BLI_edgehash_insert ( edgehash, MIN2(mface[i].v2, mface[i].v4), MAX2(mface[i].v2, mface[i].v4), NULL ); + } + } + + cloth->numsprings = struct_springs + shear_springs + bend_springs; if ( edgelist ) -- cgit v1.2.3 From 373f142530e288610ace4cf650ad7abb316f5586 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 2 Mar 2008 22:01:43 +0000 Subject: Cloth: Bugfix for IRIX compile (hopefully), bugfix for multiple springs (appeared on triangles), _test_ for inlining on msvc --- source/blender/blenkernel/intern/cloth.c | 41 +++++++++++++++++--------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 63982e4162a..d933dffad17 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1330,6 +1330,10 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) // shear springs for ( i = 0; i < numfaces; i++ ) { + // triangle faces already have shear springs due to structural geometry + if ( mface[i].v4 ) + continue; + spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); if(!spring) @@ -1351,29 +1355,28 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) BLI_linklist_prepend ( &cloth->springs, spring ); - if ( mface[i].v4 ) + + // if ( mface[i].v4 ) --> Quad face + spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); + + if(!spring) { - spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); - - if(!spring) - { - cloth_free_errorsprings(cloth, edgehash, edgelist); - return 0; - } + cloth_free_errorsprings(cloth, edgehash, edgelist); + return 0; + } - spring->ij = MIN2(mface[i].v2, mface[i].v4); - spring->kl = MAX2(mface[i].v4, mface[i].v2); - VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); - spring->type = CLOTH_SPRING_TYPE_SHEAR; - spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; + spring->ij = MIN2(mface[i].v2, mface[i].v4); + spring->kl = MAX2(mface[i].v4, mface[i].v2); + VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x ); + spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->type = CLOTH_SPRING_TYPE_SHEAR; + spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; - BLI_linklist_append ( &edgelist[spring->ij], spring ); - BLI_linklist_append ( &edgelist[spring->kl], spring ); - shear_springs++; + BLI_linklist_append ( &edgelist[spring->ij], spring ); + BLI_linklist_append ( &edgelist[spring->kl], spring ); + shear_springs++; - BLI_linklist_prepend ( &cloth->springs, spring ); - } + BLI_linklist_prepend ( &cloth->springs, spring ); } // bending springs -- cgit v1.2.3 From 8dbd6e2b03971e557ae7d1d3a6fbc15029b83cee Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Sun, 2 Mar 2008 23:20:20 +0000 Subject: Cloth bugfix - stupid typo resulted in missing diagonal springs (reported by nudelZ on #blendercoders) --- source/blender/blenkernel/intern/cloth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d933dffad17..ee857805fb5 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1331,7 +1331,7 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) for ( i = 0; i < numfaces; i++ ) { // triangle faces already have shear springs due to structural geometry - if ( mface[i].v4 ) + if ( !mface[i].v4 ) continue; spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" ); @@ -1428,10 +1428,10 @@ int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) for ( i = 0; i < numfaces; i++ ) // edge springs { - BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL ); - if(mface[i].v4) { + BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL ); + BLI_edgehash_insert ( edgehash, MIN2(mface[i].v2, mface[i].v4), MAX2(mface[i].v2, mface[i].v4), NULL ); } } -- cgit v1.2.3 From 3ebcb390906a2d0e4685d3fbf374c7a5eb740874 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 6 Mar 2008 01:21:40 +0000 Subject: Cloth bugfix for jumpy cloth (users were complaining), so the mass can be changed on GUI now (reference: in old blendfiles, mass=1.0 was used) --- source/blender/blenkernel/intern/cloth.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index ee857805fb5..f312a331975 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -970,9 +970,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) (clmd->sim_parms->vgroup_bend>0))) { for ( i = 0; i < numverts; i++, verts++ ) - { - verts->mass = 1.0; // standard mass - + { dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { @@ -1029,6 +1027,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d float tnull[3] = {0,0,0}; int cache_there = 0; Cloth *cloth = NULL; + MFace *mfaces = NULL; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) @@ -1091,7 +1090,8 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d } /* no GUI interface yet */ - verts->mass = clmd->sim_parms->mass = 1.0f; + verts->mass = clmd->sim_parms->mass; + verts->impulse_count = 0; if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ) verts->goal= clmd->sim_parms->defgoal; -- cgit v1.2.3 From b4e13ae575b886d245c4953150cd23edbf91c4ba Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 7 Mar 2008 03:24:23 +0000 Subject: Another big purge of warnings. (Main culprits this time were Campbell and Geoffrey): * no newline at end of file (2-3) * uninitialised vars (1) * unused vars (1-2) * assigning/comparing pointers and ints (numerous) * etc. --- source/blender/blenkernel/intern/cloth.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f312a331975..b0f8cc9c330 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1027,7 +1027,6 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d float tnull[3] = {0,0,0}; int cache_there = 0; Cloth *cloth = NULL; - MFace *mfaces = NULL; // If we have a clothObject, free it. if ( clmd->clothObject != NULL ) -- cgit v1.2.3 From 33a6bf610eb66ef6c306d5b8759043960edc8052 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 12 Mar 2008 01:42:39 +0000 Subject: Cloth bugfix for 1. reset of cloth sim during render with vector blur when cache was not protected, 2. fix of bad vector blur for cloth, put fluidsim like function in to get real speed vectors --- source/blender/blenkernel/intern/cloth.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index b0f8cc9c330..d7dc96abfac 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -738,20 +738,21 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d /* 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); + /* prevent freeing when used with vectorblur */ + if(!useRenderParams) + { + 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("dt > 1.0 || dt < 0.0, %f\n", framenr); + printf("dt > 1.0 || dt < 0.0, %f, st: %f, ct: %f\n", framenr, clmd->sim_parms->sim_time, current_time); if(cloth_read_cache(ob, clmd, framenr)) { cloth_to_object (ob, clmd, result); @@ -761,7 +762,11 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d { /* 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; + { + /* prevent freeing when used with vectorblur */ + if(!useRenderParams) + clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; + } } clmd->sim_parms->sim_time = current_time; } -- cgit v1.2.3 From 51c58f3ca2dd86ed0382997f46f36a8686b427a7 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 12 Mar 2008 10:41:47 +0000 Subject: Bugfix for wrong initial cloth settings pretending to be cotton --- source/blender/blenkernel/intern/cloth.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d7dc96abfac..3d5de19c1fc 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -144,12 +144,12 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->gravity [0] = 0.0; clmd->sim_parms->gravity [1] = 0.0; clmd->sim_parms->gravity [2] = -9.81; - clmd->sim_parms->structural = 30.0; - clmd->sim_parms->shear = 30.0; - clmd->sim_parms->bending = 1.0; - clmd->sim_parms->Cdis = 1.0; // was 5 + clmd->sim_parms->structural = 15.0; + clmd->sim_parms->shear = 15.0; + clmd->sim_parms->bending = 0.5; + clmd->sim_parms->Cdis = 5.0; clmd->sim_parms->Cvi = 1.0; - clmd->sim_parms->mass = 1.0f; + clmd->sim_parms->mass = 0.3f; clmd->sim_parms->stepsPerFrame = 5; clmd->sim_parms->sim_time = 1.0; clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT; -- cgit v1.2.3 From df27557b81d8463c4274d11f4131be619da255f1 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 13 Mar 2008 22:45:36 +0000 Subject: Cloth header cleanup, bugfix (again) in wind calculation, bugfix for not working fields mindist GUI option --- source/blender/blenkernel/intern/cloth.c | 125 +------------------------------ 1 file changed, 2 insertions(+), 123 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 3d5de19c1fc..d2834571316 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -28,52 +28,22 @@ * ***** END GPL/BL DUAL LICENSE BLOCK ***** */ - -#include -#include -#include - #include "MEM_guardedalloc.h" -/* types */ -#include "DNA_curve_types.h" -#include "DNA_object_types.h" -#include "DNA_object_force.h" +#include "BKE_cloth.h" + #include "DNA_cloth_types.h" -#include "DNA_key_types.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_lattice_types.h" #include "DNA_scene_types.h" -#include "DNA_modifier_types.h" -#include "BLI_blenlib.h" -#include "BLI_arithb.h" -#include "BLI_editVert.h" -#include "BLI_edgehash.h" -#include "BLI_linklist.h" - -#include "BKE_curve.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" #include "BKE_cdderivedmesh.h" -#include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_global.h" -#include "BKE_key.h" -#include "BKE_mesh.h" #include "BKE_object.h" -#include "BKE_cloth.h" #include "BKE_modifier.h" #include "BKE_utildefines.h" -#include "BKE_DerivedMesh.h" -#include "BIF_editdeform.h" -#include "BIF_editkey.h" -#include "DNA_screen_types.h" -#include "BSE_headerbuttons.h" -#include "BIF_screen.h" -#include "BIF_space.h" -#include "mydevice.h" #include "BKE_pointcache.h" @@ -287,97 +257,6 @@ void bvh_update_from_cloth(ClothModifierData *clmd, int moving) bvh_update(bvh, moving); } -DerivedMesh *CDDM_create_tearing ( ClothModifierData *clmd, DerivedMesh *dm ) -{ - DerivedMesh *result = NULL; - unsigned int i = 0, a = 0, j=0; - int numverts = dm->getNumVerts ( dm ); - int numfaces = dm->getNumFaces ( dm ); - - MVert *mvert = CDDM_get_verts ( dm ); - MFace *mface = CDDM_get_faces ( dm ); - - MVert *mvert2; - MFace *mface2; - EdgeHash *edgehash = NULL; - Cloth *cloth = clmd->clothObject; - ClothSpring *springs = (ClothSpring *)cloth->springs; - unsigned int numsprings = cloth->numsprings; - - // create spring tearing hash - edgehash = BLI_edgehash_new(); - - for ( i = 0; i < numsprings; i++ ) - { - if ( ( springs[i].flags & CLOTH_SPRING_FLAG_DEACTIVATE ) - && ( !BLI_edgehash_haskey ( edgehash, springs[i].ij, springs[i].kl ) ) ) - { - BLI_edgehash_insert ( edgehash, springs[i].ij, springs[i].kl, NULL ); - BLI_edgehash_insert ( edgehash, springs[i].kl, springs[i].ij, NULL ); - j++; - } - } - - // printf("found %d tears\n", j); - - result = CDDM_from_template ( dm, numverts, 0, numfaces ); - - if ( !result ) - return NULL; - - // do verts - mvert2 = CDDM_get_verts ( result ); - for ( a=0; av1 = mface[a].v1; - mf->v2 = mface[a].v2; - mf->v3 = mface[a].v3; - mf->v4 = mface[a].v4; - - test_index_face ( mf, NULL, 0, 4 ); - - i++; - } - } - - CDDM_lower_num_faces ( result, i ); - CDDM_calc_edges ( result ); - CDDM_calc_normals ( result ); - - BLI_edgehash_free ( edgehash, NULL ); - - return result; -} - int modifiers_indexInObject(Object *ob, ModifierData *md_seek); int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) -- cgit v1.2.3 From 7c1a21c385ac8450e295f73a71f104ab17a076c5 Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Mon, 17 Mar 2008 21:45:40 +0000 Subject: Collision Modifier/KDOP: Rearrange things to be more generic. Also fix possible crash if not enough memory there. --- source/blender/blenkernel/intern/cloth.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d2834571316..a58fdab8c91 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -190,11 +190,6 @@ BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon) // springs = cloth->springs; // numsprings = cloth->numsprings; - - bvh->flags = 0; - bvh->leaf_tree = NULL; - bvh->leaf_root = NULL; - bvh->tree = NULL; bvh->epsilon = epsilon; bvh->numfaces = cloth->numfaces; @@ -211,20 +206,9 @@ 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; - } - for(i = 0; i < bvh->numverts; i++) { VECCOPY(bvh->current_x[i].co, verts[i].tx); - VECCOPY(bvh->current_xold[i].co, verts[i].txold); } bvh_build (bvh); -- cgit v1.2.3 From fef157ac075f84bdd7bfc39a1234aa6b31024bdf Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Tue, 8 Apr 2008 12:55:35 +0000 Subject: Cloth bugfix: used old dm instead of new created result derivedmesh; Code cleanup + deactivation of unsued selfcollision code in kdop.c + little speedup there --- source/blender/blenkernel/intern/cloth.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index a58fdab8c91..1ece51a9425 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -423,9 +423,9 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d numverts = result->getNumVerts(result); numedges = result->getNumEdges(result); numfaces = result->getNumFaces(result); - mvert = dm->getVertArray(result); - medge = dm->getEdgeArray(result); - mface = dm->getFaceArray(result); + mvert = result->getVertArray(result); + medge = result->getEdgeArray(result); + mface = result->getFaceArray(result); /* check if cache is active / if file is already saved */ /* -- cgit v1.2.3 From 906666a4d87b7812e0945acb5803be3ca43fcdbb Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Wed, 9 Apr 2008 16:38:26 +0000 Subject: Cloth enhancement for upcomming cache changes: support different speed using clmd->sim_parms->timescale --- source/blender/blenkernel/intern/cloth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 1ece51a9425..6123b1b5e35 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -135,6 +135,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->firstcachedframe = -1.0; clmd->sim_parms->avg_spring_len = 0.0; clmd->sim_parms->presets = 2; /* cotton as start setting */ + clmd->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */ clmd->coll_parms->self_friction = 5.0; clmd->coll_parms->friction = 5.0; @@ -447,7 +448,7 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *d } // unused in the moment, calculated seperately in implicit.c - clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame; + clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame; if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) ) { -- cgit v1.2.3 From 1fe5302cce8de1bad875ad29a3fcff06d0c59654 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 10 Apr 2008 11:39:20 +0000 Subject: Point Cache Refactoring ======================= Caching and Baking: - The point cache is now cleared on DAG_object_flush_update(), and not cleared for time dependency graph updates. - There is now a Bake button instead of Protect. Also cache start and end frames were added to softbody and particles. - The cloth autoprotect feature was removed. - The Ctrl+B menu now also bakes cloth and particles next to softbody and fluids. Additionally there are now frree bake and free cache menu entries. - The point cache api has been changed. There is now a PTCacheID struct for each point cache type that can be filled and then used to call the point cache functions. - PointCache struct was added to DNA and is automatically allocated for each physics type. - Soft body now supports Bake Editing just like cloth. - Tried to make the systems deal consistently with time ipo's and offsets. Still not sure it all works correct, but too complicated to solve completely now. Library Linking: - Added some more warnings to prevent editing settings on library linked objects. - Linked objects now read from the cache located next to the original library file, and never write to it. This restores old behavior for softbodies. For local simulation the mesh and not the object should be linked. - Dupligroups and proxies can't create local point caches at the moment, how to implement that I'm not sure. We probably need a proxy point cache for that to work (ugh). Physics UI: - Renamed deflection panel to collision for consistency and reorganized the buttons. Also removed some softbody collision buttons from the softbody panel that were duplicated in this panel for cloth. - Tweaked field panel buttons to not jump around when changing options. - Tabbing e.g. Soft Body Collision into the Soft Body panel, it now only shows Collision to make the panel names readable. - I tried to make enabled/disabling physics more consistent, since all three system did things different. Now the two modifier buttons to enable the modifier for the viewport and rendering are also duplicated in the physics panels. Toggling the Soft Body and Cloth buttons now both remove their modifiers. - Fixed modifier error drawing glitch. Particles: - Particles are now recalculated more often than before. Previously it did partial updates based on the changes, but that doesn't work well with DAG_object_flush_update() .. - Fixed memory leak loading keyed particle system. Now keys are not written to file anymore but always created after loading. - Make particle threads work with autothreads. Continue Physics: - The timeline play now has a Continue Physics option in the playback menu, which keeps the simulations going without writing them to the cache. - This doesn't always work that well, some changes are not immediately updated, but this can be improved later. Still it's fun to get a feel for the physics. Todo: - Point cache can get out of sync with and undo and changing a file without saving it. - Change the point cache file format to store a version (so old point cache files can be either converted or at least ignored), and to do correct endian conversion. - Menu item and/or buttons for Ctrl+B. - A system("rm ..") was changed to remove() since the former is very slow for clearing point caches. These system() calls were already giving trouble in a bug in the tracker, but really most use of this system("") should be changed and tested. - The Soft Body Collision and Clot Collision panel titles don't mention there's point cache settings there too, doing that makes them unreadable with the default panel setup.. but may need to make the names longer anyway. --- source/blender/blenkernel/intern/cloth.c | 539 +++++++++++-------------------- 1 file changed, 194 insertions(+), 345 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 6123b1b5e35..15f4051c109 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -34,6 +34,7 @@ #include "DNA_cloth_types.h" #include "DNA_mesh_types.h" +#include "DNA_object_force.h" #include "DNA_scene_types.h" #include "BKE_deform.h" @@ -92,7 +93,7 @@ static CM_SOLVER_DEF solvers [] = */ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh *dm); static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm ); -static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr); +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first); int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ); static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ); @@ -121,18 +122,11 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->Cvi = 1.0; clmd->sim_parms->mass = 0.3f; clmd->sim_parms->stepsPerFrame = 5; - clmd->sim_parms->sim_time = 1.0; - clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT; + clmd->sim_parms->flags = 0; clmd->sim_parms->solver_type = 0; clmd->sim_parms->preroll = 0; clmd->sim_parms->maxspringlen = 10; - clmd->sim_parms->firstframe = 1; - clmd->sim_parms->lastframe = 250; clmd->sim_parms->vgroup_mass = 0; - clmd->sim_parms->lastcachedframe = 0; - clmd->sim_parms->editedframe = 0; - 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->sim_parms->timescale = 1.0f; /* speed factor, describes how fast cloth moves */ @@ -246,395 +240,266 @@ int modifiers_indexInObject(Object *ob, ModifierData *md_seek); int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr) { - FILE *fp = NULL; - int stack_index = -1; - unsigned int a, ret = 1; + PTCacheID pid; + PTCacheFile *pf; Cloth *cloth = clmd->clothObject; + unsigned int a, ret = 1; if(!cloth) return 0; - stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index); - if(!fp) - ret = 0; - else { - for(a = 0; a < cloth->numverts; a++) - { - if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3) - { + BKE_ptcache_id_from_cloth(&pid, ob, clmd); + pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr); + if(pf) { + for(a = 0; a < cloth->numverts; a++) { + if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].x, 3)) { ret = 0; break; } - if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3) - { + if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].xconst, 3)) { ret = 0; break; } - if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3) - { + if(!BKE_ptcache_file_read_floats(pf, cloth->verts[a].v, 3)) { ret = 0; break; } } - fclose(fp); - - if(clmd->sim_parms->lastcachedframe < framenr) - { - if(G.rt > 0) - printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe); - } - - if(G.rt > 0) - printf("cloth_read_cache: %f successfully \n", framenr); + BKE_ptcache_file_close(pf); } - - if(G.rt > 0) - printf("cloth_read_cache: %f\n", framenr); + else + ret = 0; return ret; } void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr) { - int stack_index = -1; + PTCacheID pid; + BKE_ptcache_id_from_cloth(&pid, ob, clmd); + // don't do anything as long as we're in editmode! - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE) - { - /* delete cache free request */ - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; - + if(pid.cache->flag & PTCACHE_BAKE_EDIT_ACTIVE) return; - } - - /* clear cache if specific frame cleaning requested or cache is not protected */ - if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE)) - { - stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index); - - /* update last cached frame # */ - clmd->sim_parms->lastcachedframe = framenr; - - /* update first cached frame # */ - if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0)) - clmd->sim_parms->firstcachedframe = -1.0; - - if(G.rt > 0) - printf("cloth_clear_cache: %f\n", framenr); - } - - /* delete cache free request */ - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; - + BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_AFTER, framenr); } + void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr) { - FILE *fp = NULL; - int stack_index = -1; - unsigned int a; Cloth *cloth = clmd->clothObject; - - if(G.rt > 0) - printf("cloth_write_cache: %f\n", framenr); + PTCacheID pid; + PTCacheFile *pf; + unsigned int a; if(!cloth) - { - if(G.rt > 0) - printf("cloth_write_cache: no cloth\n"); return; - } - - stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index); - if(!fp) - { - if(G.rt > 0) - printf("cloth_write_cache: no fp\n"); + BKE_ptcache_id_from_cloth(&pid, ob, clmd); + pf = BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr); + if(!pf) return; - } - for(a = 0; a < cloth->numverts; a++) - { - fwrite(&cloth->verts[a].x, sizeof(float),3,fp); - fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp); - fwrite(&cloth->verts[a].v, sizeof(float),3,fp); + for(a = 0; a < cloth->numverts; a++) { + BKE_ptcache_file_write_floats(pf, cloth->verts[a].x, 3); + BKE_ptcache_file_write_floats(pf, cloth->verts[a].xconst, 3); + BKE_ptcache_file_write_floats(pf, cloth->verts[a].v, 3); } - /* update last cached frame # */ - clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr); + BKE_ptcache_file_close(pf); +} + +static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) +{ + PointCache *cache; + + cache= clmd->point_cache; + + /* initialize simulation data if it didn't exist already */ + if(clmd->clothObject == NULL) { + if(!cloth_from_object(ob, clmd, result, framenr, 1)) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + return 0; + } + + if(clmd->clothObject == NULL) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + return 0; + } - /* update first cached frame # */ - if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0))) - clmd->sim_parms->firstcachedframe = framenr; + implicit_set_positions(clmd); + } + + return 1; +} + +static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr) +{ + ClothVertex *verts = NULL; + Cloth *cloth; + ListBase *effectors = NULL; + MVert *mvert; + int i, ret = 0; + + /* simulate 1 frame forward */ + cloth = clmd->clothObject; + verts = cloth->verts; + mvert = result->getVertArray(result); + + /* force any pinned verts to their constrained location. */ + for(i = 0; i < clmd->clothObject->numverts; i++, verts++) { + /* save the previous position. */ + VECCOPY(verts->xold, verts->xconst); + VECCOPY(verts->txold, verts->x); + + /* Get the current position. */ + VECCOPY(verts->xconst, mvert[i].co); + Mat4MulVecfl(ob->obmat, verts->xconst); + } - if(G.rt > 0) - printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr); + tstart(); + + /* call the solver. */ + if(solvers [clmd->sim_parms->solver_type].solver) + ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors); + + tend(); - fclose(fp); + /* printf ( "Cloth simulation time: %f\n", ( float ) tval() ); */ + + return ret; } /************************************************ * clothModifier_do - main simulation function ************************************************/ -DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) - +DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) { - unsigned int i; - Cloth *cloth = clmd->clothObject; - float framenr = G.scene->r.cfra; - float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 ); - ListBase *effectors = NULL; - ClothVertex *verts = NULL; - float deltaTime = current_time - clmd->sim_parms->sim_time; - unsigned int numverts = -1; - unsigned int numedges = -1; - unsigned int numfaces = -1; - MVert *mvert = NULL; - MEdge *medge = NULL; - MFace *mface = NULL; - DerivedMesh *result = NULL; - int ret = 0; - - if(G.rt > 0) - printf("clothModifier_do start\n"); - - /* we're getting called two times during file load, - resulting in a not valid G.relbase on the first time (cache makes problems) - --> just return back */ - if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED) && (!G.relbase_valid)) - { - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED; - return dm; - } - + DerivedMesh *result; + PointCache *cache; + PTCacheID pid; + float timescale; + int framedelta, framenr, startframe, endframe; + + framenr= (int)G.scene->r.cfra; + cache= clmd->point_cache; result = CDDM_copy(dm); - - if(!result) - { + + BKE_ptcache_id_from_cloth(&pid, ob, clmd); + BKE_ptcache_id_time(&pid, framenr, &startframe, &endframe, ×cale); + clmd->sim_parms->timescale= timescale; + + /* TODO: use timescale somewhere! */ + + if(!result) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; return dm; } - numverts = result->getNumVerts(result); - numedges = result->getNumEdges(result); - numfaces = result->getNumFaces(result); - mvert = result->getVertArray(result); - medge = result->getEdgeArray(result); - mface = result->getFaceArray(result); - - /* check if cache is active / if file is already saved */ - /* - if ((!G.relbase_valid) && ( deltaTime != 1.0f )) - { - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; -} - */ - - if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET) - { - 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) + /* verify we still have the same number of vertices, if not do nothing. + * note that this should only happen if the number of vertices changes + * during an animation due to a preceding modifier, this should not + * happen because of object changes! */ + if(clmd->clothObject) { + if(result->getNumVerts(result) != clmd->clothObject->numverts) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; return result; + } } // unused in the moment, calculated seperately in implicit.c clmd->sim_parms->dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame; - - if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) ) - { - /* only force free the cache if we have a different number of verts */ - if(clmd->clothObject && (numverts != clmd->clothObject->numverts )) - { - if(G.rt > 0) - printf("Force Freeing: numverts != clmd->clothObject->numverts\n"); - - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; - cloth_free_modifier ( ob, clmd ); - } - - cloth_clear_cache(ob, clmd, 0); - - if ( !cloth_from_object ( ob, clmd, result, framenr ) ) - return result; - - if ( clmd->clothObject == NULL ) + + /* handle continuous simulation with the play button */ + if(BKE_ptcache_get_continue_physics()) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + + /* do simulation */ + if(!do_init_cloth(ob, clmd, result, framenr)) return result; - - cloth = clmd->clothObject; - - if(!cloth_read_cache(ob, clmd, framenr)) - { - /* save first frame in case we have a reseted object - and we move one frame forward. - In that case we would only start with the SECOND frame - if we don't save the current state before - TODO PROBLEM: IMHO we can't track external movement from the - first frame in this case! */ - /* - if ( deltaTime == 1.0f ) - cloth_write_cache(ob, clmd, framenr-1.0); - */ - if(G.rt > 0) - printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n"); - } - else - { - if(G.rt > 0) - printf("cloth_from_object cloth_read_cache\n"); - - implicit_set_positions(clmd); - } - - clmd->sim_parms->sim_time = current_time; - } - - // only be active during a specific period: - // that's "first frame" and "last frame" on GUI - if ( current_time < clmd->sim_parms->firstframe ) - { - if(G.rt > 0) - printf("current_time < clmd->sim_parms->firstframe\n"); + + do_step_cloth(ob, clmd, result, framenr); + cloth_to_object(ob, clmd, result); + return result; } - else if ( current_time > clmd->sim_parms->lastframe ) - { - int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd); - - if(G.rt > 0) - printf("current_time > clmd->sim_parms->lastframe\n"); - - if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index)) - { - if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe)) - { - implicit_set_positions(clmd); - - // Copy the result back to the object. - cloth_to_object (ob, clmd, result); - } - } + + /* simulation is only active during a specific period */ + if(framenr < startframe) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; return result; } - - // check for autoprotection, but only if cache active - if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT) - { - 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; - } + else if(framenr > endframe) { + framenr= endframe; } - /* 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"); - - if(!cloth_read_cache(ob, clmd, framenr)) - { - verts = cloth->verts; + /* dt is unused at the moment, calculated seperately in implicit.c */ + clmd->sim_parms->dt= 1.0f/clmd->sim_parms->stepsPerFrame; - // Force any pinned verts to their constrained location. - for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ ) - { - // Save the previous position. - VECCOPY ( verts->xold, verts->xconst ); - VECCOPY ( verts->txold, verts->x ); + if(cache->flag & PTCACHE_SIMULATION_VALID) + framedelta= framenr - cache->simframe; + else + framedelta= -1; - // Get the current position. - VECCOPY ( verts->xconst, mvert[i].co ); - Mat4MulVecfl ( ob->obmat, verts->xconst ); - } - - tstart(); + /* initialize simulation data if it didn't exist already */ + if(!do_init_cloth(ob, clmd, result, framenr)) + return result; - // Call the solver. - if ( solvers [clmd->sim_parms->solver_type].solver ) - { - ret = solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors ); - } + /* try to read from cache */ + if(cloth_read_cache(ob, clmd, framenr)) { + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->simframe= framenr; - tend(); - // printf ( "Cloth simulation time: %f\n", ( float ) tval() ); - - if(ret) - cloth_write_cache(ob, clmd, framenr); - else - clmd->sim_parms->sim_time--; - } - else - { - if(G.rt > 0) - printf("clothModifier_do deltaTime=1 cacheread\n"); - implicit_set_positions(clmd); - } - - // Copy the result back to the object. + implicit_set_positions(clmd); cloth_to_object (ob, clmd, result); + + return result; } - else if(deltaTime == 0.0f) - { - if(G.rt > 0) - printf("dt = 0, %f\n", framenr); - if(cloth_read_cache(ob, clmd, framenr)) - { - cloth_to_object (ob, clmd, result); - implicit_set_positions(clmd); - } - else /* same cache parts are missing */ - { - /* jump to a non-existing frame makes sim reset if cache is not protected */ - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) - { - /* prevent freeing when used with vectorblur */ - if(!useRenderParams) - { - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE; - cloth_clear_cache(ob, clmd, 0); - - cloth_write_cache(ob, clmd, framenr); - } - } - } + else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { + /* if baked and nothing in cache, do nothing */ + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + return result; } - else - { - if(G.rt > 0) - printf("dt > 1.0 || dt < 0.0, %f, st: %f, ct: %f\n", framenr, clmd->sim_parms->sim_time, current_time); - if(cloth_read_cache(ob, clmd, framenr)) - { - cloth_to_object (ob, clmd, result); - implicit_set_positions(clmd); + + if(framenr == startframe) { + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->simframe= framenr; + + /* don't write cache on first frame, but on second frame write + * cache for frame 1 and 2 */ + } + else if(framedelta == 1) { + /* if on second frame, write cache for first frame */ + if(framenr == startframe+1) + cloth_write_cache(ob, clmd, startframe); + + /* do simulation */ + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->simframe= framenr; + + if(!do_step_cloth(ob, clmd, result, framenr)) { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; } else - { - /* jump to a non-existing frame makes sim reset if cache is not protected */ - if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) - { - /* prevent freeing when used with vectorblur */ - if(!useRenderParams) - clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET; - } - } - clmd->sim_parms->sim_time = current_time; + cloth_write_cache(ob, clmd, framenr); + + cloth_to_object (ob, clmd, result); } - + else { + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + } + return result; } @@ -702,7 +567,6 @@ void cloth_free_modifier ( Object *ob, ClothModifierData *clmd ) MEM_freeN ( cloth ); clmd->clothObject = NULL; } - clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET; } /* frees all */ @@ -888,13 +752,12 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) } } -static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr) +static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr, int first) { unsigned int i = 0; MVert *mvert = NULL; ClothVertex *verts = NULL; float tnull[3] = {0,0,0}; - int cache_there = 0; Cloth *cloth = NULL; // If we have a clothObject, free it. @@ -926,21 +789,6 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d cloth_from_mesh ( ob, clmd, dm ); - if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe)))) - { - // no cache there - cache_there = 0; - if(G.rt > 0) - printf("cache_there = 0\n"); - } - else - { - // we have a cache - cache_there = 1; - if(G.rt > 0) - printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe); - } - // create springs clmd->clothObject->springs = NULL; clmd->clothObject->numsprings = -1; @@ -951,7 +799,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d // set initial values for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ ) { - if(!cache_there) + if(first) { VECCOPY ( verts->x, mvert[i].co ); Mat4MulVecfl ( ob->obmat, verts->x ); @@ -998,10 +846,11 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d } // init our solver - if ( solvers [clmd->sim_parms->solver_type].init ) + if ( solvers [clmd->sim_parms->solver_type].init ) { solvers [clmd->sim_parms->solver_type].init ( ob, clmd ); + } - if(cache_there) + if(!first) implicit_set_positions(clmd); clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); -- cgit v1.2.3 From 0e8a6448dde5607ab979e1ec884e9bc13e59127d Mon Sep 17 00:00:00 2001 From: Daniel Genrich Date: Thu, 10 Apr 2008 18:00:59 +0000 Subject: Little cloth code cleanup needed because of from new cache code merge --- source/blender/blenkernel/intern/cloth.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 15f4051c109..d41ad6a4abf 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -393,8 +393,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh * BKE_ptcache_id_time(&pid, framenr, &startframe, &endframe, ×cale); clmd->sim_parms->timescale= timescale; - /* TODO: use timescale somewhere! */ - if(!result) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; @@ -440,9 +438,6 @@ DerivedMesh *clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh * else if(framenr > endframe) { framenr= endframe; } - - /* dt is unused at the moment, calculated seperately in implicit.c */ - clmd->sim_parms->dt= 1.0f/clmd->sim_parms->stepsPerFrame; if(cache->flag & PTCACHE_SIMULATION_VALID) framedelta= framenr - cache->simframe; -- cgit v1.2.3 From 5d0a207ecb843c4c73be897cfccbf3a0d2db574b Mon Sep 17 00:00:00 2001 From: Chris Want Date: Wed, 16 Apr 2008 22:40:48 +0000 Subject: Patch from GSR that a) fixes a whole bunch of GPL/BL license blocks that were previously missed; and b) greatly increase my ohloh stats! --- source/blender/blenkernel/intern/cloth.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'source/blender/blenkernel/intern/cloth.c') diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index d41ad6a4abf..09a51bb37a4 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1,15 +1,12 @@ /* cloth.c * * -* ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** +* ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. The Blender -* Foundation also sells licenses for use in proprietary software under -* the Blender License. See http://www.blender.org/BL/ for information -* about this. +* of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -25,7 +22,7 @@ * * Contributor(s): Daniel Genrich * -* ***** END GPL/BL DUAL LICENSE BLOCK ***** +* ***** END GPL LICENSE BLOCK ***** */ #include "MEM_guardedalloc.h" -- cgit v1.2.3