update to trunk r14199
[blender.git] / source / blender / blenkernel / intern / cloth.c
1 /*  cloth.c
2 *
3 *
4 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version. The Blender
10 * Foundation also sells licenses for use in proprietary software under
11 * the Blender License.  See http://www.blender.org/BL/ for information
12 * about this.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 *
23 * The Original Code is Copyright (C) Blender Foundation
24 * All rights reserved.
25 *
26 * Contributor(s): Daniel Genrich
27 *
28 * ***** END GPL/BL DUAL LICENSE BLOCK *****
29 */
30
31 #include "MEM_guardedalloc.h"
32
33 #include "BKE_cloth.h"
34
35 #include "DNA_cloth_types.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "BKE_deform.h"
40 #include "BKE_DerivedMesh.h"
41 #include "BKE_cdderivedmesh.h"
42 #include "BKE_effect.h"
43 #include "BKE_global.h"
44 #include "BKE_object.h"
45 #include "BKE_modifier.h"
46 #include "BKE_utildefines.h"
47
48 #include "BKE_pointcache.h"
49
50 #ifdef _WIN32
51 void tstart ( void )
52 {}
53 void tend ( void )
54 {
55 }
56 double tval()
57 {
58         return 0;
59 }
60 #else
61 #include <sys/time.h>
62                          static struct timeval _tstart, _tend;
63          static struct timezone tz;
64          void tstart ( void )
65 {
66         gettimeofday ( &_tstart, &tz );
67 }
68 void tend ( void )
69 {
70         gettimeofday ( &_tend,&tz );
71 }
72 double tval()
73 {
74         double t1, t2;
75         t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );
76         t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 );
77         return t2-t1;
78 }
79 #endif
80
81 /* Our available solvers. */
82 // 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
83 // 254 = MAX!
84 static CM_SOLVER_DEF    solvers [] =
85 {
86         { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
87         // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
88 };
89
90 /* ********** cloth engine ******* */
91 /* Prototypes for internal functions.
92 */
93 static void cloth_to_object (Object *ob,  ClothModifierData *clmd, DerivedMesh *dm);
94 static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm );
95 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr);
96 int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm );
97 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm );
98
99
100 /******************************************************************************
101 *
102 * External interface called by modifier.c clothModifier functions.
103 *
104 ******************************************************************************/
105 /**
106  * cloth_init -  creates a new cloth simulation.
107  *
108  * 1. create object
109  * 2. fill object with standard values or with the GUI settings if given
110  */
111 void cloth_init ( ClothModifierData *clmd )
112 {       
113         /* Initialize our new data structure to reasonable values. */
114         clmd->sim_parms->gravity [0] = 0.0;
115         clmd->sim_parms->gravity [1] = 0.0;
116         clmd->sim_parms->gravity [2] = -9.81;
117         clmd->sim_parms->structural = 15.0;
118         clmd->sim_parms->shear = 15.0;
119         clmd->sim_parms->bending = 0.5;
120         clmd->sim_parms->Cdis = 5.0; 
121         clmd->sim_parms->Cvi = 1.0;
122         clmd->sim_parms->mass = 0.3f;
123         clmd->sim_parms->stepsPerFrame = 5;
124         clmd->sim_parms->sim_time = 1.0;
125         clmd->sim_parms->flags = CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT;
126         clmd->sim_parms->solver_type = 0;
127         clmd->sim_parms->preroll = 0;
128         clmd->sim_parms->maxspringlen = 10;
129         clmd->sim_parms->firstframe = 1;
130         clmd->sim_parms->lastframe = 250;
131         clmd->sim_parms->vgroup_mass = 0;
132         clmd->sim_parms->lastcachedframe = 0;
133         clmd->sim_parms->editedframe = 0;
134         clmd->sim_parms->autoprotect = 25;
135         clmd->sim_parms->firstcachedframe = -1.0;
136         clmd->sim_parms->avg_spring_len = 0.0;
137         clmd->sim_parms->presets = 2; /* cotton as start setting */
138         
139         clmd->coll_parms->self_friction = 5.0;
140         clmd->coll_parms->friction = 5.0;
141         clmd->coll_parms->loop_count = 3;
142         clmd->coll_parms->epsilon = 0.015f;
143         clmd->coll_parms->flags = CLOTH_COLLSETTINGS_FLAG_ENABLED;
144         clmd->coll_parms->collision_list = NULL;
145         clmd->coll_parms->self_loop_count = 1.0;
146         clmd->coll_parms->selfepsilon = 0.75;
147
148         /* These defaults are copied from softbody.c's
149         * softbody_calc_forces() function.
150         */
151         clmd->sim_parms->eff_force_scale = 1000.0;
152         clmd->sim_parms->eff_wind_scale = 250.0;
153
154         // also from softbodies
155         clmd->sim_parms->maxgoal = 1.0f;
156         clmd->sim_parms->mingoal = 0.0f;
157         clmd->sim_parms->defgoal = 0.0f;
158         clmd->sim_parms->goalspring = 1.0f;
159         clmd->sim_parms->goalfrict = 0.0f;
160 }
161
162
163 BVH *bvh_build_from_cloth (ClothModifierData *clmd, float epsilon)
164 {
165         unsigned int i = 0;
166         BVH     *bvh=NULL;
167         Cloth *cloth = clmd->clothObject;
168         ClothVertex *verts = NULL;
169
170         if(!clmd)
171                 return NULL;
172
173         cloth = clmd->clothObject;
174
175         if(!cloth)
176                 return NULL;
177         
178         verts = cloth->verts;
179         
180         // in the moment, return zero if no faces there
181         if(!cloth->numfaces)
182                 return NULL;
183         
184         bvh = MEM_callocN(sizeof(BVH), "BVH");
185         if (bvh == NULL) 
186         {
187                 printf("bvh: Out of memory.\n");
188                 return NULL;
189         }
190         
191         // springs = cloth->springs;
192         // numsprings = cloth->numsprings;
193
194         bvh->epsilon = epsilon;
195         bvh->numfaces = cloth->numfaces;
196         bvh->mfaces = cloth->mfaces;
197
198         bvh->numverts = cloth->numverts;
199         
200         bvh->current_x = MEM_callocN ( sizeof ( MVert ) * bvh->numverts, "bvh->current_x" );
201         
202         if (bvh->current_x == NULL) 
203         {
204                 printf("bvh: Out of memory.\n");
205                 MEM_freeN(bvh);
206                 return NULL;
207         }
208         
209         for(i = 0; i < bvh->numverts; i++)
210         {
211                 VECCOPY(bvh->current_x[i].co, verts[i].tx);
212         }
213         
214         bvh_build (bvh);
215         
216         return bvh;
217 }
218
219 void bvh_update_from_cloth(ClothModifierData *clmd, int moving)
220 {
221         unsigned int i = 0;
222         Cloth *cloth = clmd->clothObject;
223         BVH *bvh = cloth->tree;
224         ClothVertex *verts = cloth->verts;
225         
226         if(!bvh)
227                 return;
228         
229         if(cloth->numverts!=bvh->numverts)
230                 return;
231         
232         if(cloth->verts)
233         {
234                 for(i = 0; i < bvh->numverts; i++)
235                 {
236                         VECCOPY(bvh->current_x[i].co, verts[i].tx);
237                         VECCOPY(bvh->current_xold[i].co, verts[i].txold);
238                 }
239         }
240         
241         bvh_update(bvh, moving);
242 }
243
244 int modifiers_indexInObject(Object *ob, ModifierData *md_seek);
245
246 int cloth_read_cache(Object *ob, ClothModifierData *clmd, float framenr)
247 {
248         FILE *fp = NULL;
249         int stack_index = -1;
250         unsigned int a, ret = 1;
251         Cloth *cloth = clmd->clothObject;
252         
253         if(!cloth)
254                 return 0;
255         
256         stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
257         
258         fp = BKE_ptcache_id_fopen((ID *)ob, 'r', framenr, stack_index);
259         if(!fp)
260                 ret = 0;
261         else {
262                 for(a = 0; a < cloth->numverts; a++)
263                 {
264                         if(fread(&cloth->verts[a].x, sizeof(float), 3, fp) != 3) 
265                         {
266                                 ret = 0;
267                                 break;
268                         }
269                         if(fread(&cloth->verts[a].xconst, sizeof(float), 3, fp) != 3) 
270                         {
271                                 ret = 0;
272                                 break;
273                         }
274                         if(fread(&cloth->verts[a].v, sizeof(float), 3, fp) != 3) 
275                         {
276                                 ret = 0;
277                                 break;
278                         }
279                 }
280                 
281                 fclose(fp);
282                 
283                 if(clmd->sim_parms->lastcachedframe < framenr)
284                 {
285                         if(G.rt > 0)
286                                 printf("cloth_read_cache problem: lnex - f#: %f, lastCF: %d\n", framenr, clmd->sim_parms->lastcachedframe);
287                 }
288                 
289                 if(G.rt > 0)
290                         printf("cloth_read_cache: %f successfully \n", framenr);
291         }
292         
293         if(G.rt > 0)
294                 printf("cloth_read_cache: %f\n", framenr);
295         
296         return ret;
297 }
298
299 void cloth_clear_cache(Object *ob, ClothModifierData *clmd, float framenr)
300 {
301         int stack_index = -1;
302         
303         // don't do anything as long as we're in editmode!
304         if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_EDITMODE)
305         {
306                 /* delete cache free request */
307                 clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
308                 
309                 return;
310         }
311         
312         /* clear cache if specific frame cleaning requested or cache is not protected */
313         if((!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT)) || (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE))
314         {
315                 stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
316                 
317                 BKE_ptcache_id_clear((ID *)ob, PTCACHE_CLEAR_AFTER, framenr, stack_index);
318                 
319                 /* update last cached frame # */
320                 clmd->sim_parms->lastcachedframe = framenr;
321                 
322                 /* update first cached frame # */
323                 if((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe >=0.0))
324                         clmd->sim_parms->firstcachedframe = -1.0;
325                 
326                 if(G.rt > 0)
327                         printf("cloth_clear_cache: %f\n", framenr);
328         }
329         
330         /* delete cache free request */
331         clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
332         
333         
334 }
335 void cloth_write_cache(Object *ob, ClothModifierData *clmd, float framenr)
336 {
337         FILE *fp = NULL;
338         int stack_index = -1;
339         unsigned int a;
340         Cloth *cloth = clmd->clothObject;
341         
342         if(G.rt > 0)
343                 printf("cloth_write_cache: %f\n", framenr);
344         
345         if(!cloth)
346         {
347                 if(G.rt > 0)
348                         printf("cloth_write_cache: no cloth\n");
349                 return;
350         }
351         
352         stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
353         
354         fp = BKE_ptcache_id_fopen((ID *)ob, 'w', framenr, stack_index);
355         if(!fp)
356         {
357                 if(G.rt > 0)
358                         printf("cloth_write_cache: no fp\n");
359                 return;
360         }
361         
362         for(a = 0; a < cloth->numverts; a++)
363         {
364                 fwrite(&cloth->verts[a].x, sizeof(float),3,fp);
365                 fwrite(&cloth->verts[a].xconst, sizeof(float),3,fp);
366                 fwrite(&cloth->verts[a].v, sizeof(float),3,fp);
367         }
368         
369         /* update last cached frame # */
370         clmd->sim_parms->lastcachedframe = MAX2(clmd->sim_parms->lastcachedframe, framenr);
371         
372         /* update first cached frame # */
373         if((clmd->sim_parms->firstcachedframe < 0.0) || ((framenr < clmd->sim_parms->firstcachedframe) && (clmd->sim_parms->firstcachedframe > 0.0)))
374                 clmd->sim_parms->firstcachedframe = framenr;
375         
376         if(G.rt > 0)
377                 printf("lcf: %d, framenr: %f\n", clmd->sim_parms->lastcachedframe, framenr);
378
379         fclose(fp);
380 }
381
382 /************************************************
383  * clothModifier_do - main simulation function
384 ************************************************/
385 DerivedMesh *clothModifier_do(ClothModifierData *clmd,Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc)
386
387 {
388         unsigned int i;
389         Cloth *cloth = clmd->clothObject;
390         float framenr = G.scene->r.cfra;
391         float current_time = bsystem_time ( ob, ( float ) G.scene->r.cfra, 0.0 );
392         ListBase *effectors = NULL;
393         ClothVertex *verts = NULL;
394         float deltaTime = current_time - clmd->sim_parms->sim_time;
395         unsigned int numverts = -1;
396         unsigned int numedges = -1;
397         unsigned int numfaces = -1;
398         MVert *mvert = NULL;
399         MEdge *medge = NULL;
400         MFace *mface = NULL;
401         DerivedMesh *result = NULL;
402         int ret = 0;
403         
404         if(G.rt > 0)
405                 printf("clothModifier_do start\n");
406         
407         /* we're getting called two times during file load,
408         resulting in a not valid G.relbase on the first time (cache makes problems)
409         --> just return back */
410         if((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_LOADED) && (!G.relbase_valid)) 
411         {
412                 clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_LOADED;
413                 return dm;
414         }
415         
416         result = CDDM_copy(dm);
417         
418         if(!result)
419         {
420                 return dm;
421         }
422         
423         numverts = result->getNumVerts(result);
424         numedges = result->getNumEdges(result);
425         numfaces = result->getNumFaces(result);
426         mvert = dm->getVertArray(result);
427         medge = dm->getEdgeArray(result);
428         mface = dm->getFaceArray(result);
429         
430         /* check if cache is active / if file is already saved */
431         /*
432         if ((!G.relbase_valid) && ( deltaTime != 1.0f ))
433         {
434         clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
435 }
436         */
437         
438         if(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_RESET)
439         {       
440                 cloth_free_modifier (ob, clmd);
441                 if(G.rt > 0)
442                         printf("clothModifier_do CLOTH_SIMSETTINGS_FLAG_RESET\n");
443                 
444                 // prevent rebuilding of cloth each time you move backward 
445                 if(deltaTime < 0.0)
446                         return result;
447         }
448         
449         // unused in the moment, calculated seperately in implicit.c
450         clmd->sim_parms->dt = 1.0f / clmd->sim_parms->stepsPerFrame;
451         
452         if ( ( clmd->clothObject == NULL ) || (clmd->clothObject && (numverts != clmd->clothObject->numverts )) )
453         {       
454                 /* only force free the cache if we have a different number of verts */
455                 if(clmd->clothObject && (numverts != clmd->clothObject->numverts ))
456                 {
457                         if(G.rt > 0)
458                                 printf("Force Freeing: numverts != clmd->clothObject->numverts\n");
459                         
460                         clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
461                         cloth_free_modifier ( ob, clmd );
462                 }
463                 
464                 cloth_clear_cache(ob, clmd, 0);
465                                 
466                 if ( !cloth_from_object ( ob, clmd, result, framenr ) )
467                         return result;
468         
469                 if ( clmd->clothObject == NULL )
470                         return result;
471         
472                 cloth = clmd->clothObject;
473                 
474                 if(!cloth_read_cache(ob, clmd, framenr))
475                 {
476                         /* save first frame in case we have a reseted object 
477                         and we move one frame forward.
478                         In that case we would only start with the SECOND frame
479                         if we don't save the current state before 
480                         TODO PROBLEM: IMHO we can't track external movement from the
481                         first frame in this case! */
482                         /*
483                         if ( deltaTime == 1.0f )
484                         cloth_write_cache(ob, clmd, framenr-1.0);
485                         */
486                         if(G.rt > 0)
487                                 printf("cloth_from_object NO cloth_read_cache cloth_write_cache\n");
488                 }
489                 else
490                 {
491                         if(G.rt > 0)
492                                 printf("cloth_from_object cloth_read_cache\n");
493                         
494                         implicit_set_positions(clmd);
495                 }
496                 
497                 clmd->sim_parms->sim_time = current_time;
498         }
499         
500         // only be active during a specific period:
501         // that's "first frame" and "last frame" on GUI
502         if ( current_time < clmd->sim_parms->firstframe )
503         {
504                 if(G.rt > 0)
505                         printf("current_time < clmd->sim_parms->firstframe\n");
506                 return result;
507         }
508         else if ( current_time > clmd->sim_parms->lastframe )
509         {
510                 int stack_index = modifiers_indexInObject(ob, (ModifierData *)clmd);
511                         
512                 if(G.rt > 0)
513                         printf("current_time > clmd->sim_parms->lastframe\n");
514                 
515                 if(BKE_ptcache_id_exist((ID *)ob, clmd->sim_parms->lastcachedframe, stack_index))
516                 {
517                         if(cloth_read_cache(ob, clmd, clmd->sim_parms->lastcachedframe))
518                         {
519                                 implicit_set_positions(clmd);
520                                 
521                                 // Copy the result back to the object.
522                                 cloth_to_object (ob, clmd, result);
523                         }
524                 }
525                 return result;
526         }
527         
528         // check for autoprotection, but only if cache active
529         if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_AUTOPROTECT)
530         {
531                 if((framenr >= clmd->sim_parms->autoprotect) && (G.relbase_valid))
532                 {
533                         if(G.rt > 0)
534                                 printf("fr#: %f, auto: %d\n", framenr, clmd->sim_parms->autoprotect);
535                         
536                         clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT;
537                 }
538         }
539         
540         /* nice moving one frame forward */
541         if ( deltaTime == 1.0f )
542         {
543                 clmd->sim_parms->sim_time = current_time;
544                         
545                 if(G.rt > 0)
546                         printf("clothModifier_do deltaTime=1\n");
547                 
548                 if(!cloth_read_cache(ob, clmd, framenr))
549                 {
550                         verts = cloth->verts;
551
552                         // Force any pinned verts to their constrained location.
553                         for ( i = 0; i < clmd->clothObject->numverts; i++, verts++ )
554                         {
555                                 // Save the previous position.
556                                 VECCOPY ( verts->xold, verts->xconst );
557                                 VECCOPY ( verts->txold, verts->x );
558
559                                 // Get the current position.
560                                 VECCOPY ( verts->xconst, mvert[i].co );
561                                 Mat4MulVecfl ( ob->obmat, verts->xconst );
562                         }
563                         
564                         tstart();
565
566                         // Call the solver.
567                         if ( solvers [clmd->sim_parms->solver_type].solver )
568                         {
569                                 ret = solvers [clmd->sim_parms->solver_type].solver ( ob, framenr, clmd, effectors );
570                         }
571
572                         tend();
573                         // printf ( "Cloth simulation time: %f\n", ( float ) tval() );
574                         
575                         if(ret)
576                                 cloth_write_cache(ob, clmd, framenr);
577                         else
578                                 clmd->sim_parms->sim_time--;
579                 }
580                 else
581                 {
582                         if(G.rt > 0)
583                                 printf("clothModifier_do deltaTime=1 cacheread\n");
584                         implicit_set_positions(clmd);
585                 }
586                 
587                 // Copy the result back to the object.
588                 cloth_to_object (ob, clmd, result);
589         }
590         else if(deltaTime == 0.0f) 
591         {       
592                 if(G.rt > 0)
593                         printf("dt = 0, %f\n", framenr);
594                 if(cloth_read_cache(ob, clmd, framenr))
595                 {
596                         cloth_to_object (ob, clmd, result);
597                         implicit_set_positions(clmd);
598                 }
599                 else /* same cache parts are missing */
600                 {
601                         /* jump to a non-existing frame makes sim reset if cache is not protected */
602                         if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
603                         {       
604                                 /* prevent freeing when used with vectorblur */
605                                 if(!useRenderParams)
606                                 {
607                                         clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_CCACHE_FFREE;
608                                         cloth_clear_cache(ob, clmd, 0);
609                                         
610                                         cloth_write_cache(ob, clmd, framenr);
611                                 }
612                         }
613                 }
614         }
615         else
616         {       
617                 if(G.rt > 0)
618                         printf("dt > 1.0 || dt < 0.0, %f, st: %f, ct: %f\n", framenr, clmd->sim_parms->sim_time, current_time);
619                 if(cloth_read_cache(ob, clmd, framenr))
620                 {
621                         cloth_to_object (ob, clmd, result);
622                         implicit_set_positions(clmd);
623                 }
624                 else
625                 {
626                         /* jump to a non-existing frame makes sim reset if cache is not protected */
627                         if(!(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_CCACHE_PROTECT))
628                         {
629                                 /* prevent freeing when used with vectorblur */
630                                 if(!useRenderParams)
631                                         clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_RESET;
632                         }
633                 }
634                 clmd->sim_parms->sim_time = current_time;
635         }
636         
637         return result;
638 }
639
640 /* frees all */
641 void cloth_free_modifier ( Object *ob, ClothModifierData *clmd )
642 {
643         Cloth   *cloth = NULL;
644         
645         if ( !clmd )
646                 return;
647
648         cloth = clmd->clothObject;
649
650         
651         if ( cloth )
652         {       
653                 // If our solver provides a free function, call it
654                 if ( solvers [clmd->sim_parms->solver_type].free )
655                 {
656                         solvers [clmd->sim_parms->solver_type].free ( clmd );
657                 }
658
659                 // Free the verts.
660                 if ( cloth->verts != NULL )
661                         MEM_freeN ( cloth->verts );
662
663                 cloth->verts = NULL;
664                 cloth->numverts = 0;
665
666                 // Free the springs.
667                 if ( cloth->springs != NULL )
668                 {
669                         LinkNode *search = cloth->springs;
670                         while(search)
671                         {
672                                 ClothSpring *spring = search->link;
673                                                 
674                                 MEM_freeN ( spring );
675                                 search = search->next;
676                         }
677                         BLI_linklist_free(cloth->springs, NULL);
678                 
679                         cloth->springs = NULL;
680                 }
681
682                 cloth->springs = NULL;
683                 cloth->numsprings = 0;
684
685                 // free BVH collision tree
686                 if ( cloth->tree )
687                         bvh_free ( ( BVH * ) cloth->tree );
688
689                 // we save our faces for collision objects
690                 if ( cloth->mfaces )
691                         MEM_freeN ( cloth->mfaces );
692                 
693                 if(cloth->edgehash)
694                         BLI_edgehash_free ( cloth->edgehash, NULL );
695                 
696                 
697                 /*
698                 if(clmd->clothObject->facemarks)
699                 MEM_freeN(clmd->clothObject->facemarks);
700                 */
701                 MEM_freeN ( cloth );
702                 clmd->clothObject = NULL;
703         }
704         clmd->sim_parms->flags &= ~CLOTH_SIMSETTINGS_FLAG_RESET;
705 }
706
707 /* frees all */
708 void cloth_free_modifier_extern ( ClothModifierData *clmd )
709 {
710         Cloth   *cloth = NULL;
711         if(G.rt > 0)
712                 printf("cloth_free_modifier_extern\n");
713         
714         if ( !clmd )
715                 return;
716
717         cloth = clmd->clothObject;
718         
719         if ( cloth )
720         {       
721                 if(G.rt > 0)
722                         printf("cloth_free_modifier_extern in\n");
723                 
724                 // If our solver provides a free function, call it
725                 if ( solvers [clmd->sim_parms->solver_type].free )
726                 {
727                         solvers [clmd->sim_parms->solver_type].free ( clmd );
728                 }
729
730                 // Free the verts.
731                 if ( cloth->verts != NULL )
732                         MEM_freeN ( cloth->verts );
733
734                 cloth->verts = NULL;
735                 cloth->numverts = 0;
736
737                 // Free the springs.
738                 if ( cloth->springs != NULL )
739                 {
740                         LinkNode *search = cloth->springs;
741                         while(search)
742                         {
743                                 ClothSpring *spring = search->link;
744                                                 
745                                 MEM_freeN ( spring );
746                                 search = search->next;
747                         }
748                         BLI_linklist_free(cloth->springs, NULL);
749                 
750                         cloth->springs = NULL;
751                 }
752
753                 cloth->springs = NULL;
754                 cloth->numsprings = 0;
755
756                 // free BVH collision tree
757                 if ( cloth->tree )
758                         bvh_free ( ( BVH * ) cloth->tree );
759
760                 // we save our faces for collision objects
761                 if ( cloth->mfaces )
762                         MEM_freeN ( cloth->mfaces );
763                 
764                 if(cloth->edgehash)
765                         BLI_edgehash_free ( cloth->edgehash, NULL );
766                 
767                 
768                 /*
769                 if(clmd->clothObject->facemarks)
770                 MEM_freeN(clmd->clothObject->facemarks);
771                 */
772                 MEM_freeN ( cloth );
773                 clmd->clothObject = NULL;
774         }
775 }
776
777 /******************************************************************************
778 *
779 * Internal functions.
780 *
781 ******************************************************************************/
782
783 /**
784  * cloth_to_object - copies the deformed vertices to the object.
785  *
786  **/
787 static void cloth_to_object (Object *ob,  ClothModifierData *clmd, DerivedMesh *dm)
788 {
789         unsigned int    i = 0;
790         MVert *mvert = NULL;
791         unsigned int numverts;
792         Cloth *cloth = clmd->clothObject;
793
794         if (clmd->clothObject) {
795                 /* inverse matrix is not uptodate... */
796                 Mat4Invert (ob->imat, ob->obmat);
797
798                 mvert = CDDM_get_verts(dm);
799                 numverts = dm->getNumVerts(dm);
800
801                 for (i = 0; i < numverts; i++)
802                 {
803                         VECCOPY (mvert[i].co, cloth->verts[i].x);
804                         Mat4MulVecfl (ob->imat, mvert[i].co);   /* cloth is in global coords */
805                 }
806         }
807 }
808
809
810 /**
811  * cloth_apply_vgroup - applies a vertex group as specified by type
812  *
813  **/
814 /* can be optimized to do all groups in one loop */
815 static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
816 {
817         unsigned int i = 0;
818         unsigned int j = 0;
819         MDeformVert *dvert = NULL;
820         Cloth *clothObj = NULL;
821         unsigned int numverts = dm->getNumVerts ( dm );
822         float goalfac = 0;
823         ClothVertex *verts = NULL;
824
825         clothObj = clmd->clothObject;
826
827         if ( !dm )
828                 return;
829         
830         numverts = dm->getNumVerts ( dm );
831
832         verts = clothObj->verts;
833         
834         if (((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) || 
835                      (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) && 
836                      ((clmd->sim_parms->vgroup_mass>0) || 
837                      (clmd->sim_parms->vgroup_struct>0)||
838                      (clmd->sim_parms->vgroup_bend>0)))
839         {
840                 for ( i = 0; i < numverts; i++, verts++ )
841                 {       
842                         dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT );
843                         if ( dvert )
844                         {
845                                 for ( j = 0; j < dvert->totweight; j++ )
846                                 {
847                                         if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL ))
848                                         {
849                                                 verts->goal = dvert->dw [j].weight;
850                                                 goalfac= 1.0f;
851                                                 
852                                                 /*
853                                                 // Kicking goal factor to simplify things...who uses that anyway?
854                                                 // ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
855                                                 */
856                                                 
857                                                 verts->goal  = ( float ) pow ( verts->goal , 4.0f );
858                                                 if ( verts->goal >=SOFTGOALSNAP )
859                                                 {
860                                                         verts->flags |= CLOTH_VERT_FLAG_PINNED;
861                                                 }
862                                         }
863                                         
864                                         if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING )
865                                         {
866                                                 if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_struct-1))
867                                                 {
868                                                         verts->struct_stiff = dvert->dw [j].weight;
869                                                         verts->shear_stiff = dvert->dw [j].weight;
870                                                 }
871                                                 
872                                                 if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_bend-1))
873                                                 {
874                                                         verts->bend_stiff = dvert->dw [j].weight;
875                                                 }
876                                         }
877                                         /*
878                                         // for later
879                                         if( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_weight-1))
880                                         {
881                                                 verts->mass = dvert->dw [j].weight;
882                                         }
883                                         */
884                                 }
885                         }
886                 }
887         }
888 }
889
890 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float framenr)
891 {
892         unsigned int i = 0;
893         MVert *mvert = NULL;
894         ClothVertex *verts = NULL;
895         float tnull[3] = {0,0,0};
896         int cache_there = 0;
897         Cloth *cloth = NULL;
898
899         // If we have a clothObject, free it. 
900         if ( clmd->clothObject != NULL )
901         {
902                 cloth_free_modifier ( ob, clmd );
903                 if(G.rt > 0)
904                         printf("cloth_free_modifier cloth_from_object\n");
905         }
906
907         // Allocate a new cloth object.
908         clmd->clothObject = MEM_callocN ( sizeof ( Cloth ), "cloth" );
909         if ( clmd->clothObject )
910         {
911                 clmd->clothObject->old_solver_type = 255;
912                 // clmd->clothObject->old_collision_type = 255;
913                 cloth = clmd->clothObject;
914                 clmd->clothObject->edgehash = NULL;
915         }
916         else if ( !clmd->clothObject )
917         {
918                 modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject." );
919                 return 0;
920         }
921
922         // mesh input objects need DerivedMesh
923         if ( !dm )
924                 return 0;
925
926         cloth_from_mesh ( ob, clmd, dm );
927
928         if((clmd->sim_parms->firstcachedframe < 0.0) || ((clmd->sim_parms->firstcachedframe >= 0.0) && (!cloth_read_cache(ob, clmd, clmd->sim_parms->firstcachedframe))))
929         {
930                 // no cache there
931                 cache_there = 0;
932                 if(G.rt > 0)
933                         printf("cache_there = 0\n");
934         }
935         else
936         {
937                 // we have a cache
938                 cache_there = 1;
939                 if(G.rt > 0)
940                         printf("cache_there = 1, fcf: %d\n", clmd->sim_parms->firstcachedframe);
941         }
942         
943         // create springs 
944         clmd->clothObject->springs = NULL;
945         clmd->clothObject->numsprings = -1;
946         
947         mvert = dm->getVertArray ( dm );
948         verts = clmd->clothObject->verts;
949
950         // set initial values
951         for ( i = 0; i < dm->getNumVerts(dm); i++, verts++ )
952         {
953                 if(!cache_there)
954                 {
955                         VECCOPY ( verts->x, mvert[i].co );
956                         Mat4MulVecfl ( ob->obmat, verts->x );
957                 }
958                 
959                 /* no GUI interface yet */
960                 verts->mass = clmd->sim_parms->mass; 
961                 verts->impulse_count = 0;
962
963                 if ( clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )
964                         verts->goal= clmd->sim_parms->defgoal;
965                 else
966                         verts->goal= 0.0f;
967
968                 verts->flags = 0;
969                 VECCOPY ( verts->xold, verts->x );
970                 VECCOPY ( verts->xconst, verts->x );
971                 VECCOPY ( verts->txold, verts->x );
972                 VecMulf ( verts->v, 0.0f );
973
974                 verts->impulse_count = 0;
975                 VECCOPY ( verts->impulse, tnull );
976         }
977         
978         // apply / set vertex groups
979         // has to be happen before springs are build!
980         cloth_apply_vgroup (clmd, dm);
981         
982         
983         if ( !cloth_build_springs ( clmd, dm ) )
984         {
985                 cloth_free_modifier ( ob, clmd );
986                 modifier_setError ( & ( clmd->modifier ), "Can't build springs." );
987                 printf("cloth_free_modifier cloth_build_springs\n");
988                 return 0;
989         }
990         
991         for ( i = 0; i < dm->getNumVerts(dm); i++)
992         {
993                 if((!(cloth->verts[i].flags & CLOTH_VERT_FLAG_PINNED)) && (cloth->verts[i].goal > ALMOST_ZERO))
994                 {
995                         cloth_add_spring (clmd, i, i, 0.0, CLOTH_SPRING_TYPE_GOAL);
996                 }
997         }
998         
999         // init our solver
1000         if ( solvers [clmd->sim_parms->solver_type].init )
1001                 solvers [clmd->sim_parms->solver_type].init ( ob, clmd );
1002         
1003         if(cache_there)
1004                 implicit_set_positions(clmd);
1005
1006         clmd->clothObject->tree = bvh_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
1007
1008         return 1;
1009 }
1010
1011
1012 static void cloth_from_mesh ( Object *ob, ClothModifierData *clmd, DerivedMesh *dm )
1013 {
1014         unsigned int numverts = dm->getNumVerts ( dm );
1015         unsigned int numfaces = dm->getNumFaces ( dm );
1016         MFace *mface = CDDM_get_faces(dm);
1017         unsigned int i = 0;
1018
1019         /* Allocate our vertices. */
1020         clmd->clothObject->numverts = numverts;
1021         clmd->clothObject->verts = MEM_callocN ( sizeof ( ClothVertex ) * clmd->clothObject->numverts, "clothVertex" );
1022         if ( clmd->clothObject->verts == NULL )
1023         {
1024                 cloth_free_modifier ( ob, clmd );
1025                 modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->verts." );
1026                 printf("cloth_free_modifier clmd->clothObject->verts\n");
1027                 return;
1028         }
1029
1030         // save face information
1031         clmd->clothObject->numfaces = numfaces;
1032         clmd->clothObject->mfaces = MEM_callocN ( sizeof ( MFace ) * clmd->clothObject->numfaces, "clothMFaces" );
1033         if ( clmd->clothObject->mfaces == NULL )
1034         {
1035                 cloth_free_modifier ( ob, clmd );
1036                 modifier_setError ( & ( clmd->modifier ), "Out of memory on allocating clmd->clothObject->mfaces." );
1037                 printf("cloth_free_modifier clmd->clothObject->mfaces\n");
1038                 return;
1039         }
1040         for ( i = 0; i < numfaces; i++ )
1041                 memcpy ( &clmd->clothObject->mfaces[i], &mface[i], sizeof ( MFace ) );
1042
1043         /* Free the springs since they can't be correct if the vertices
1044         * changed.
1045         */
1046         if ( clmd->clothObject->springs != NULL )
1047                 MEM_freeN ( clmd->clothObject->springs );
1048
1049 }
1050
1051 /***************************************************************************************
1052 * SPRING NETWORK BUILDING IMPLEMENTATION BEGIN
1053 ***************************************************************************************/
1054
1055 // be carefull: implicit solver has to be resettet when using this one!
1056 // --> only for implicit handling of this spring!
1057 int cloth_add_spring ( ClothModifierData *clmd, unsigned int indexA, unsigned int indexB, float restlength, int spring_type)
1058 {
1059         Cloth *cloth = clmd->clothObject;
1060         ClothSpring *spring = NULL;
1061         
1062         if(cloth)
1063         {
1064                 // TODO: look if this spring is already there
1065                 
1066                 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
1067                 
1068                 if(!spring)
1069                         return 0;
1070                 
1071                 spring->ij = indexA;
1072                 spring->kl = indexB;
1073                 spring->restlen =  restlength;
1074                 spring->type = spring_type;
1075                 spring->flags = 0;
1076                 spring->stiffness = 0;
1077                 
1078                 cloth->numsprings++;
1079         
1080                 BLI_linklist_prepend ( &cloth->springs, spring );
1081                 
1082                 return 1;
1083         }
1084         return 0;
1085 }
1086
1087 void cloth_free_errorsprings(Cloth *cloth, EdgeHash *edgehash, LinkNode **edgelist)
1088 {
1089         unsigned int i = 0;
1090         
1091         if ( cloth->springs != NULL )
1092         {
1093                 LinkNode *search = cloth->springs;
1094                 while(search)
1095                 {
1096                         ClothSpring *spring = search->link;
1097                                                 
1098                         MEM_freeN ( spring );
1099                         search = search->next;
1100                 }
1101                 BLI_linklist_free(cloth->springs, NULL);
1102                 
1103                 cloth->springs = NULL;
1104         }
1105         
1106         if(edgelist)
1107         {
1108                 for ( i = 0; i < cloth->numverts; i++ )
1109                 {
1110                         BLI_linklist_free ( edgelist[i],NULL );
1111                 }
1112
1113                 MEM_freeN ( edgelist );
1114         }
1115         
1116         if(cloth->edgehash)
1117                 BLI_edgehash_free ( cloth->edgehash, NULL );
1118 }
1119
1120 int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm )
1121 {
1122         Cloth *cloth = clmd->clothObject;
1123         ClothSpring *spring = NULL, *tspring = NULL, *tspring2 = NULL;
1124         unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
1125         unsigned int i = 0;
1126         unsigned int numverts = dm->getNumVerts ( dm );
1127         unsigned int numedges = dm->getNumEdges ( dm );
1128         unsigned int numfaces = dm->getNumFaces ( dm );
1129         MEdge *medge = CDDM_get_edges ( dm );
1130         MFace *mface = CDDM_get_faces ( dm );
1131         unsigned int index2 = 0; // our second vertex index
1132         LinkNode **edgelist = NULL;
1133         EdgeHash *edgehash = NULL;
1134         LinkNode *search = NULL, *search2 = NULL;
1135         float temp[3];
1136         
1137         // error handling
1138         if ( numedges==0 )
1139                 return 0;
1140
1141         cloth->springs = NULL;
1142
1143         edgelist = MEM_callocN ( sizeof ( LinkNode * ) * numverts, "cloth_edgelist_alloc" );
1144         
1145         if(!edgelist)
1146                 return 0;
1147         
1148         for ( i = 0; i < numverts; i++ )
1149         {
1150                 edgelist[i] = NULL;
1151         }
1152
1153         if ( cloth->springs )
1154                 MEM_freeN ( cloth->springs );
1155
1156         // create spring network hash
1157         edgehash = BLI_edgehash_new();
1158
1159         // structural springs
1160         for ( i = 0; i < numedges; i++ )
1161         {
1162                 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
1163
1164                 if ( spring )
1165                 {
1166                         spring->ij = MIN2(medge[i].v1, medge[i].v2);
1167                         spring->kl = MAX2(medge[i].v2, medge[i].v1);
1168                         VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
1169                         spring->restlen =  sqrt ( INPR ( temp, temp ) );
1170                         clmd->sim_parms->avg_spring_len += spring->restlen;
1171                         cloth->verts[spring->ij].avg_spring_len += spring->restlen;
1172                         cloth->verts[spring->kl].avg_spring_len += spring->restlen;
1173                         cloth->verts[spring->ij].spring_count++;
1174                         cloth->verts[spring->kl].spring_count++;
1175                         spring->type = CLOTH_SPRING_TYPE_STRUCTURAL;
1176                         spring->flags = 0;
1177                         spring->stiffness = (cloth->verts[spring->kl].struct_stiff + cloth->verts[spring->ij].struct_stiff) / 2.0;
1178                         struct_springs++;
1179                         
1180                         BLI_linklist_prepend ( &cloth->springs, spring );
1181                 }
1182                 else
1183                 {
1184                         cloth_free_errorsprings(cloth, edgehash, edgelist);
1185                         return 0;
1186                 }
1187         }
1188         
1189         if(struct_springs > 0)
1190                 clmd->sim_parms->avg_spring_len /= struct_springs;
1191         
1192         for(i = 0; i < numverts; i++)
1193         {
1194                 cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49 / ((float)cloth->verts[i].spring_count);
1195         }
1196         
1197         // shear springs
1198         for ( i = 0; i < numfaces; i++ )
1199         {
1200                 // triangle faces already have shear springs due to structural geometry
1201                 if ( !mface[i].v4 )
1202                         continue; 
1203                 
1204                 spring = ( ClothSpring *) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
1205                 
1206                 if(!spring)
1207                 {
1208                         cloth_free_errorsprings(cloth, edgehash, edgelist);
1209                         return 0;
1210                 }
1211
1212                 spring->ij = MIN2(mface[i].v1, mface[i].v3);
1213                 spring->kl = MAX2(mface[i].v3, mface[i].v1);
1214                 VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
1215                 spring->restlen =  sqrt ( INPR ( temp, temp ) );
1216                 spring->type = CLOTH_SPRING_TYPE_SHEAR;
1217                 spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
1218
1219                 BLI_linklist_append ( &edgelist[spring->ij], spring );
1220                 BLI_linklist_append ( &edgelist[spring->kl], spring );
1221                 shear_springs++;
1222
1223                 BLI_linklist_prepend ( &cloth->springs, spring );
1224
1225                 
1226                 // if ( mface[i].v4 ) --> Quad face
1227                 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
1228                 
1229                 if(!spring)
1230                 {
1231                         cloth_free_errorsprings(cloth, edgehash, edgelist);
1232                         return 0;
1233                 }
1234
1235                 spring->ij = MIN2(mface[i].v2, mface[i].v4);
1236                 spring->kl = MAX2(mface[i].v4, mface[i].v2);
1237                 VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
1238                 spring->restlen =  sqrt ( INPR ( temp, temp ) );
1239                 spring->type = CLOTH_SPRING_TYPE_SHEAR;
1240                 spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0;
1241
1242                 BLI_linklist_append ( &edgelist[spring->ij], spring );
1243                 BLI_linklist_append ( &edgelist[spring->kl], spring );
1244                 shear_springs++;
1245
1246                 BLI_linklist_prepend ( &cloth->springs, spring );
1247         }
1248         
1249         // bending springs
1250         search2 = cloth->springs;
1251         for ( i = struct_springs; i < struct_springs+shear_springs; i++ )
1252         {
1253                 if ( !search2 )
1254                         break;
1255
1256                 tspring2 = search2->link;
1257                 search = edgelist[tspring2->kl];
1258                 while ( search )
1259                 {
1260                         tspring = search->link;
1261                         index2 = ( ( tspring->ij==tspring2->kl ) ? ( tspring->kl ) : ( tspring->ij ) );
1262                         
1263                         // check for existing spring
1264                         // check also if startpoint is equal to endpoint
1265                         if ( !BLI_edgehash_haskey ( edgehash, MIN2(tspring2->ij, index2), MAX2(tspring2->ij, index2) )
1266                         && ( index2!=tspring2->ij ) )
1267                         {
1268                                 spring = ( ClothSpring * ) MEM_callocN ( sizeof ( ClothSpring ), "cloth spring" );
1269                                 
1270                                 if(!spring)
1271                                 {
1272                                         cloth_free_errorsprings(cloth, edgehash, edgelist);
1273                                         return 0;
1274                                 }
1275
1276                                 spring->ij = MIN2(tspring2->ij, index2);
1277                                 spring->kl = MAX2(tspring2->ij, index2);
1278                                 VECSUB ( temp, cloth->verts[spring->kl].x, cloth->verts[spring->ij].x );
1279                                 spring->restlen =  sqrt ( INPR ( temp, temp ) );
1280                                 spring->type = CLOTH_SPRING_TYPE_BENDING;
1281                                 spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0;
1282                                 BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL );
1283                                 bend_springs++;
1284
1285                                 BLI_linklist_prepend ( &cloth->springs, spring );
1286                         }
1287                         search = search->next;
1288                 }
1289                 search2 = search2->next;
1290         }
1291         
1292         /* insert other near springs in edgehash AFTER bending springs are calculated (for selfcolls) */
1293         for ( i = 0; i < numedges; i++ ) // struct springs
1294                 BLI_edgehash_insert ( edgehash, MIN2(medge[i].v1, medge[i].v2), MAX2(medge[i].v2, medge[i].v1), NULL );
1295         
1296         for ( i = 0; i < numfaces; i++ ) // edge springs
1297         {
1298                 if(mface[i].v4)
1299                 {
1300                         BLI_edgehash_insert ( edgehash, MIN2(mface[i].v1, mface[i].v3), MAX2(mface[i].v3, mface[i].v1), NULL );
1301                         
1302                         BLI_edgehash_insert ( edgehash, MIN2(mface[i].v2, mface[i].v4), MAX2(mface[i].v2, mface[i].v4), NULL );
1303                 }
1304         }
1305         
1306         
1307         cloth->numsprings = struct_springs + shear_springs + bend_springs;
1308         
1309         if ( edgelist )
1310         {
1311                 for ( i = 0; i < numverts; i++ )
1312                 {
1313                         BLI_linklist_free ( edgelist[i],NULL );
1314                 }
1315         
1316                 MEM_freeN ( edgelist );
1317         }
1318         
1319         cloth->edgehash = edgehash;
1320         
1321         if(G.rt>0)
1322                 printf("avg_len: %f\n",clmd->sim_parms->avg_spring_len);
1323
1324         return 1;
1325
1326 } /* cloth_build_springs */
1327 /***************************************************************************************
1328 * SPRING NETWORK BUILDING IMPLEMENTATION END
1329 ***************************************************************************************/
1330