Fix: kicked springs caching since it's unused and needs lots of memory
[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 * The Original Code is: all of this file.
27 *
28 * Contributor(s): none yet.
29 *
30 * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32
33
34 #include <math.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "MEM_guardedalloc.h"
39
40 /* types */
41 #include "DNA_curve_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_object_force.h"
44 #include "DNA_cloth_types.h"    
45 #include "DNA_key_types.h"
46 #include "DNA_mesh_types.h"
47 #include "DNA_meshdata_types.h"
48 #include "DNA_lattice_types.h"
49 #include "DNA_scene_types.h"
50 #include "DNA_modifier_types.h"
51
52 #include "BLI_blenlib.h"
53 #include "BLI_arithb.h"
54 #include "BLI_edgehash.h"
55 #include "BLI_linklist.h"
56
57 #include "BKE_curve.h"
58 #include "BKE_deform.h"
59 #include "BKE_DerivedMesh.h"
60 #include "BKE_cdderivedmesh.h"
61 #include "BKE_displist.h"
62 #include "BKE_effect.h"
63 #include "BKE_global.h"
64 #include "BKE_key.h"
65 #include "BKE_mesh.h"
66 #include "BKE_object.h"
67 #include "BKE_cloth.h"
68 #include "BKE_modifier.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_DerivedMesh.h"
71 #include "BIF_editdeform.h"
72 #include "BIF_editkey.h"
73 #include "DNA_screen_types.h"
74 #include "BSE_headerbuttons.h"
75 #include "BIF_screen.h"
76 #include "BIF_space.h"
77 #include "mydevice.h"
78
79 #ifdef _WIN32
80 void tstart(void)
81 {
82 }
83 void tend(void)
84 {
85
86 }
87 double tval()
88 {
89         return 0;
90 }
91 #else
92 #include <sys/time.h>
93 static struct timeval _tstart, _tend;
94 static struct timezone tz;
95 void tstart(void)
96 {
97         gettimeofday(&_tstart, &tz);
98 }
99 void tend(void)
100 {
101         gettimeofday(&_tend,&tz);
102 }
103 double tval()
104 {
105         double t1, t2;
106         t1 =  (double)_tstart.tv_sec + (double)_tstart.tv_usec/(1000*1000);
107         t2 =  (double)_tend.tv_sec + (double)_tend.tv_usec/(1000*1000);
108         return t2-t1;
109 }
110 #endif
111
112 /* Our available solvers. */
113 // 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
114 // 254 = MAX!
115 static CM_SOLVER_DEF    solvers [] = {
116         { "Implicit", CM_IMPLICIT, implicit_init, implicit_solver, implicit_free },
117         // { "Implicit C++", CM_IMPLICITCPP, implicitcpp_init, implicitcpp_solver, implicitcpp_free },
118 };
119
120 /* ********** cloth engine ******* */
121 /* Prototypes for internal functions.
122 */
123 static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts);
124 static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm);
125 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts);
126 static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts);
127 int cloth_build_springs(Cloth *cloth, DerivedMesh *dm);
128 static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup);
129
130
131 /******************************************************************************
132 *
133 * External interface called by modifier.c clothModifier functions.
134 *
135 ******************************************************************************/
136 /**
137 * cloth_init -  creates a new cloth simulation.
138 *
139 * 1. create object
140 * 2. fill object with standard values or with the GUI settings if given 
141 */
142 void cloth_init (ClothModifierData *clmd)
143 {
144         /* Initialize our new data structure to reasonable values. */
145         clmd->sim_parms.gravity [0] = 0.0;
146         clmd->sim_parms.gravity [1] = 0.0;
147         clmd->sim_parms.gravity [2] = -9.81;
148         clmd->sim_parms.structural = 100.0;
149         clmd->sim_parms.shear = 100.0;
150         clmd->sim_parms.bending = 1.0;
151         clmd->sim_parms.Cdis = 5.0;
152         clmd->sim_parms.Cvi = 1.0;
153         clmd->sim_parms.mass = 1.0f;
154         clmd->sim_parms.stepsPerFrame = 5;
155         clmd->sim_parms.sim_time = 1.0;
156         clmd->sim_parms.flags = CSIMSETT_FLAG_RESET;
157         clmd->sim_parms.solver_type = 0; 
158         clmd->sim_parms.preroll = 0;
159         clmd->sim_parms.maxspringlen = 10;
160         clmd->sim_parms.firstframe = 1;
161         clmd->sim_parms.lastframe = 250;
162         clmd->coll_parms.self_friction = 5.0;
163         clmd->coll_parms.friction = 10.0;
164         clmd->coll_parms.loop_count = 1;
165         clmd->coll_parms.epsilon = 0.01f;
166         
167         /* These defaults are copied from softbody.c's
168         * softbody_calc_forces() function.
169         */
170         clmd->sim_parms.eff_force_scale = 1000.0;
171         clmd->sim_parms.eff_wind_scale = 250.0;
172
173         // also from softbodies
174         clmd->sim_parms.maxgoal = 1.0f;
175         clmd->sim_parms.mingoal = 0.0f;
176         clmd->sim_parms.defgoal = 0.7f;
177         clmd->sim_parms.goalspring = 100.0f;
178         clmd->sim_parms.goalfrict = 0.0f;
179
180         clmd->sim_parms.cache = NULL;
181 }
182
183 // unused in the moment, cloth needs quads from mesh
184 DerivedMesh *CDDM_convert_to_triangle(DerivedMesh *dm)
185 {
186         DerivedMesh *result = NULL;
187         int i;
188         int numverts = dm->getNumVerts(dm);
189         int numedges = dm->getNumEdges(dm);
190         int numfaces = dm->getNumFaces(dm);
191
192         MVert *mvert = CDDM_get_verts(dm);
193         MEdge *medge = CDDM_get_edges(dm);
194         MFace *mface = CDDM_get_faces(dm);
195
196         MVert *mvert2;
197         MFace *mface2;
198         unsigned int numtris=0;
199         unsigned int numquads=0;
200         int a = 0;
201         int random = 0;
202         int firsttime = 0;
203         float vec1[3], vec2[3], vec3[3], vec4[3], vec5[3];
204         float mag1=0, mag2=0;
205
206         for(i = 0; i < numfaces; i++)
207         {
208                 if(mface[i].v4)
209                         numquads++;
210                 else
211                         numtris++;      
212         }
213
214         result = CDDM_from_template(dm, numverts, 0, numtris + 2*numquads);
215
216         if(!result)
217                 return NULL;
218
219         // do verts
220         mvert2 = CDDM_get_verts(result);
221         for(a=0; a<numverts; a++) 
222         {
223                 MVert *inMV;
224                 MVert *mv = &mvert2[a];
225
226                 inMV = &mvert[a];
227
228                 DM_copy_vert_data(dm, result, a, a, 1);
229                 *mv = *inMV;
230         }
231
232
233         // do faces
234         mface2 = CDDM_get_faces(result);
235         for(a=0, i=0; a<numfaces; a++) 
236         {
237                 MFace *mf = &mface2[i];
238                 MFace *inMF;
239                 inMF = &mface[a];
240
241                 /*
242                 DM_copy_face_data(dm, result, a, i, 1);
243
244                 *mf = *inMF;
245                 */
246
247                 if(mface[a].v4 && random==1)
248                 {
249                         mf->v1 = mface[a].v2;
250                         mf->v2 = mface[a].v3;
251                         mf->v3 = mface[a].v4;
252                 }
253                 else
254                 {
255                         mf->v1 = mface[a].v1;
256                         mf->v2 = mface[a].v2;
257                         mf->v3 = mface[a].v3;
258                 }
259
260                 mf->v4 = 0;
261                 mf->flag |= ME_SMOOTH;
262
263                 test_index_face(mf, NULL, 0, 3);
264
265                 if(mface[a].v4)
266                 {
267                         MFace *mf2;
268
269                         i++;
270
271                         mf2 = &mface2[i];
272                         /*
273                         DM_copy_face_data(dm, result, a, i, 1);
274
275                         *mf2 = *inMF;
276                         */
277
278                         if(random==1)
279                         {
280                                 mf2->v1 = mface[a].v1;
281                                 mf2->v2 = mface[a].v2;
282                                 mf2->v3 = mface[a].v4;
283                         }
284                         else
285                         {
286                                 mf2->v1 = mface[a].v4;
287                                 mf2->v2 = mface[a].v1;
288                                 mf2->v3 = mface[a].v3;
289                         }
290                         mf2->v4 = 0;
291                         mf2->flag |= ME_SMOOTH;
292
293                         test_index_face(mf2, NULL, 0, 3);
294                 }
295
296                 i++;
297         }
298
299         CDDM_calc_edges(result);
300         CDDM_calc_normals(result);
301
302         return result;
303
304 }
305
306
307 DerivedMesh *CDDM_create_tearing(ClothModifierData *clmd, DerivedMesh *dm)
308 {
309         DerivedMesh *result = NULL;
310         unsigned int i = 0, a = 0, j=0;
311         int numverts = dm->getNumVerts(dm);
312         int numedges = dm->getNumEdges(dm);
313         int numfaces = dm->getNumFaces(dm);
314
315         MVert *mvert = CDDM_get_verts(dm);
316         MEdge *medge = CDDM_get_edges(dm);
317         MFace *mface = CDDM_get_faces(dm);
318
319         MVert *mvert2;
320         MFace *mface2;
321         unsigned int numtris=0;
322         unsigned int numquads=0;
323         EdgeHash *edgehash = NULL;
324         Cloth *cloth = clmd->clothObject;
325         ClothSpring *springs = cloth->springs;
326         unsigned int numsprings = cloth->numsprings;
327         
328         // create spring tearing hash
329         edgehash = BLI_edgehash_new();
330         
331         for(i = 0; i < numsprings; i++)
332         {
333                 if((springs[i].flags & CSPRING_FLAG_DEACTIVATE)
334                 &&(!BLI_edgehash_haskey(edgehash, springs[i].ij, springs[i].kl)))
335                 {
336                         BLI_edgehash_insert(edgehash, springs[i].ij, springs[i].kl, NULL);
337                         BLI_edgehash_insert(edgehash, springs[i].kl, springs[i].ij, NULL);
338                         j++;
339                 }
340         }
341         
342         // printf("found %d tears\n", j);
343         
344         result = CDDM_from_template(dm, numverts, 0, numfaces);
345
346         if(!result)
347                 return NULL;
348
349         // do verts
350         mvert2 = CDDM_get_verts(result);
351         for(a=0; a<numverts; a++) 
352         {
353                 MVert *inMV;
354                 MVert *mv = &mvert2[a];
355
356                 inMV = &mvert[a];
357
358                 DM_copy_vert_data(dm, result, a, a, 1);
359                 *mv = *inMV;
360         }
361
362
363         // do faces
364         mface2 = CDDM_get_faces(result);
365         for(a=0, i=0; a<numfaces; a++) 
366         {
367                 MFace *mf = &mface2[i];
368                 MFace *inMF;
369                 inMF = &mface[a];
370
371                 /*
372                 DM_copy_face_data(dm, result, a, i, 1);
373
374                 *mf = *inMF;
375                 */
376                 
377                 if((!BLI_edgehash_haskey(edgehash, mface[a].v1, mface[a].v2))
378                 &&(!BLI_edgehash_haskey(edgehash, mface[a].v2, mface[a].v3))
379                 &&(!BLI_edgehash_haskey(edgehash, mface[a].v3, mface[a].v4))
380                 &&(!BLI_edgehash_haskey(edgehash, mface[a].v4, mface[a].v1)))
381                 {
382                         mf->v1 = mface[a].v1;
383                         mf->v2 = mface[a].v2;
384                         mf->v3 = mface[a].v3;
385                         mf->v4 = mface[a].v4;
386         
387                         test_index_face(mf, NULL, 0, 4);
388         
389                         i++;
390                 }
391         }
392
393         CDDM_lower_num_faces(result, i);
394         CDDM_calc_edges(result);
395         CDDM_calc_normals(result);
396         
397         BLI_edgehash_free(edgehash, NULL);
398
399         return result;
400 }
401
402
403 int cloth_cache_search_frame(ClothModifierData *clmd, float time)
404 {
405         Frame *frame = NULL;
406         LinkNode *search = NULL;
407         int newtime = time + clmd->sim_parms.preroll;
408
409         Cloth *cloth = NULL;
410
411         if(!clmd)
412                 return 0;
413
414         cloth = clmd->clothObject;
415
416         if(!cloth)
417                 return 0;
418
419         if(clmd->sim_parms.cache)
420         {               
421                 search = clmd->sim_parms.cache;
422
423                 // check if frame exists
424                 while(search)
425                 {
426                         frame = search->link;
427
428                         if(frame->time == newtime)
429                                 break;
430
431                         frame = NULL;
432
433                         search = search->next;   
434                 }
435         }       
436
437         if(!frame) 
438                 return 0;
439
440         return 1;
441 }
442
443 int cloth_cache_last_frame(ClothModifierData *clmd)
444 {
445         Frame *frame = NULL;
446         LinkNode *search = NULL;
447         int temptime = 0;
448
449         Cloth *cloth = NULL;
450
451         if(!clmd)
452                 return 0;
453
454         cloth = clmd->clothObject;
455
456         if(!cloth)
457                 return 0;
458
459         if(clmd->sim_parms.cache)
460         {               
461                 search = clmd->sim_parms.cache;
462
463                 // check if frame exists
464                 while(search)
465                 {
466                         frame = search->link;
467
468                         if(frame->time > temptime)
469                         {
470                                 temptime = frame->time;
471                         }
472
473                         search = search->next;
474                 }
475         }       
476
477         return temptime;
478 }
479
480 void cloth_cache_get_frame(ClothModifierData *clmd, float time)
481 {
482         Frame *frame = NULL;
483         LinkNode *search = NULL;
484         unsigned int i = 0;
485         Cloth *cloth = NULL;
486         int newtime = time + clmd->sim_parms.preroll;
487
488         if(clmd)
489         {
490                 cloth = clmd->clothObject;
491
492                 if(!cloth)
493                         return;
494
495                 // get cache
496                 if(clmd->sim_parms.cache)
497                 {
498                         search = clmd->sim_parms.cache;
499                         frame = NULL;
500                         // check if frame exists
501                         while(search)
502                         {
503                                 frame = search->link;
504                                 if(frame->time == newtime)
505                                         break;
506
507                                 frame = NULL;
508
509                                 search = search->next;   
510                         }
511
512                         if(frame)
513                         {
514                                 if(frame->verts)
515                                 {
516
517                                         // copy ClothVertex struct
518                                         memcpy(cloth->verts, frame->verts, cloth->numverts*sizeof(ClothVertex));
519                                         implicit_set_positions(clmd);
520                                 }
521                                 /*
522                                 if(frame->springs)
523                                 {
524                                         // copy ClothSpring struct
525                                         memcpy(cloth->springs, frame->springs, cloth->numsprings*sizeof(ClothSpring));
526                                 }
527                                 */
528                         }
529                 }
530         }
531
532 }
533
534 void cloth_cache_set_frame(ClothModifierData *clmd, float time)
535 {
536         Frame *frame = NULL;
537         unsigned int i = 0;
538         Cloth *cloth = NULL;
539         int newtime = time + clmd->sim_parms.preroll;
540
541         if(clmd)
542         {
543                 cloth = clmd->clothObject;
544
545                 if(cloth)
546                 {
547                         // creat new frame cache
548                         frame = (Frame *)MEM_callocN(sizeof(Frame), "cloth frame cache");
549                         frame->verts = (ClothVertex *)MEM_callocN(sizeof(ClothVertex)*cloth->numverts, "cloth frame vertex cache");
550                         frame->springs = NULL;
551                         /*
552                         frame->springs = (ClothSpring *)MEM_callocN(sizeof(ClothSpring)*cloth->numsprings, "cloth frame spring cache");
553                         */
554                         frame->time = newtime;
555
556                         // copy ClothVertex struct
557                         for(i = 0; i < cloth->numverts; i++)
558                         {
559                                 memcpy(&frame->verts[i], &cloth->verts[i], sizeof(ClothVertex));
560                         }
561                         /*
562                         // copy ClothSpring struct
563                         for(i = 0; i < cloth->numsprings; i++)
564                         {
565                                 memcpy(&frame->springs[i], &cloth->springs[i], sizeof(ClothSpring));
566                         }
567                         */
568                 }
569                 if(frame)
570                 {
571                         if(!clmd->sim_parms.cache)
572                                 BLI_linklist_prepend(&clmd->sim_parms.cache, frame);
573                         else
574                                 BLI_linklist_append(&clmd->sim_parms.cache, frame);
575                 }
576         }
577 }
578
579 void cloth_cache_free(ClothModifierData *clmd, float time)
580 {
581         Frame *frame = NULL;
582         LinkNode *search, *last_search;
583         int newtime = time + clmd->sim_parms.preroll;
584
585         // do never free first cached frame
586         if((newtime<1.0f) && !(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL))
587                 return;
588
589         /* Calls the solver and collision frees first as they
590         * might depend on data in clmd->clothObject. */
591
592         if (clmd) 
593         {
594                 if(clmd->sim_parms.cache)
595                 {                       
596                         last_search = search = clmd->sim_parms.cache;
597                         while(search)
598                         {
599                                 LinkNode *next= search->next;
600                                 frame = search->link;
601
602                                 // free part of cache, but not preroll cache and first framer
603                                 if((clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_PART)  
604                                         && (frame->time > newtime)) // do not delete the first frame
605                                 {
606                                         MEM_freeN(frame->verts);
607                                         // MEM_freeN(frame->springs);
608                                         MEM_freeN(frame);       
609                                         MEM_freeN(search);
610                                         last_search->next = next;
611                                 }
612                                 else if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL) // free COMPLETE cache
613                                 {
614                                         MEM_freeN(frame->verts);
615                                         // MEM_freeN(frame->springs);
616                                         MEM_freeN(frame);       
617                                 }
618                                 else
619                                         last_search = search;
620                                 search = next;
621                         }
622
623                         if(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_FREE_ALL)
624                         {
625                                 BLI_linklist_free(clmd->sim_parms.cache,NULL); 
626                                 clmd->sim_parms.cache = NULL;
627                         }
628                 }
629         }
630
631         /* clear flags */
632         clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_FREE_ALL;
633         clmd->sim_parms.flags &= ~CSIMSETT_FLAG_CCACHE_FREE_PART;
634
635 }
636
637
638 /**
639 * cloth_deform_verts - simulates one step, framenr is in frames.
640
641 **/
642 void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
643                 float (*vertexCos)[3], int numverts)
644 {
645         unsigned int i;
646         unsigned int numedges = -1;
647         unsigned int numfaces = -1;
648         MVert *mvert = NULL;
649         MEdge *medge = NULL;
650         MFace *mface = NULL;
651         DerivedMesh *result = NULL, *result2 = NULL;
652         Cloth *cloth = clmd->clothObject;
653         unsigned int framenr = (float)G.scene->r.cfra;
654         float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
655         ListBase        *effectors = NULL;
656         ClothVertex *newframe= NULL, *verts;
657         Frame *frame = NULL;
658         LinkNode *search = NULL;
659         float deltaTime = current_time - clmd->sim_parms.sim_time;      
660         
661         // only be active during a specific period
662         if(current_time < clmd->sim_parms.firstframe)
663                 return;
664         else if(current_time > clmd->sim_parms.lastframe)
665         {
666                 int frametime = cloth_cache_last_frame(clmd);
667                 if(cloth_cache_search_frame(clmd, frametime))
668                 {
669                         cloth_cache_get_frame(clmd, frametime);
670                         cloth_to_object (ob, clmd, vertexCos, numverts);
671                 }
672                 return;
673         }
674         else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed
675         {
676                 if(!cloth_cache_search_frame(clmd, framenr))
677                         return;
678         }
679         
680         // unused in the moment
681         clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame;
682         
683         clmd->sim_parms.sim_time = current_time;
684         
685         // check if cloth object was some collision object before and needs freeing now
686         if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) && (clmd->clothObject != NULL) && (clmd->clothObject->old_solver_type == 255))
687         {
688                 // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing 
689                 clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ;
690                 cloth_free_modifier(clmd);
691                 clmd->sim_parms.flags &= ~CSIMSETT_FLAG_COLLOBJ;
692         }
693
694         // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ
695         if (clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
696         {                               
697                 
698                 // save next position + time            
699                 if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) )
700                 {
701                         if(!collobj_from_object (ob, clmd, dm, vertexCos, framenr))
702                                 return;
703
704                         if(clmd->clothObject == NULL)
705                                 return;
706
707                         cloth = clmd->clothObject;
708                 }
709
710                 // Save old position 
711                 clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time;
712                 clmd->sim_parms.sim_time = current_time; 
713                 
714                 verts = cloth->verts;
715
716                 for (i = 0; i < clmd->clothObject->numverts; i++, verts++)
717                 {
718                         // Save the previous position. 
719                         VECCOPY (verts->xold, verts->x);
720                         VECCOPY (verts->txold, verts->x);
721
722                         // Get the current position. 
723                         VECCOPY (verts->x, vertexCos[i]);
724                         Mat4MulVecfl(ob->obmat, verts->x);
725
726                         // Compute the vertices velocity. 
727                         VECSUB (verts->v, verts->x, verts->xold);
728                 }
729                 
730                 return;
731         }       
732
733         if(deltaTime == 1.0f)
734         {
735                 if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) 
736                 {
737                         if(!cloth_from_object (ob, clmd, dm, vertexCos, numverts))
738                                 return;
739
740                         if(clmd->clothObject == NULL)
741                                 return;
742
743                         cloth = clmd->clothObject;
744                 }
745
746                 clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type;
747
748                 // Insure we have a clmd->clothObject, in case allocation failed.
749                 if (clmd->clothObject != NULL) 
750                 {            
751                         if(!cloth_cache_search_frame(clmd, framenr))
752                         {
753                                 verts = cloth->verts;
754                                 
755                                 /* Force any pinned verts to their constrained location. */
756                                 for (i = 0; i < clmd->clothObject->numverts; i++, verts++)
757                                 {
758                                         /* Save the previous position. */
759                                         VECCOPY (verts->xold, verts->xconst);
760                                         VECCOPY (verts->txold, verts->x);
761
762                                         /* Get the current position. */
763                                         VECCOPY (verts->xconst, vertexCos[i]);
764                                         Mat4MulVecfl(ob->obmat, verts->xconst);
765
766                                         /* Compute the vertices velocity. */
767                                         VECSUB (verts->v, verts->xconst, verts->xold);
768                                 }
769
770                                 tstart();
771
772                                 /* Call the solver. */
773                                 if (solvers [clmd->sim_parms.solver_type].solver)
774                                         solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors,0,0);
775
776                                 tend();
777                                 printf("Cloth simulation time: %f\n", (float)tval());
778
779                                 cloth_cache_set_frame(clmd, framenr);
780
781                         }
782                         else // just retrieve the cached frame
783                         {
784                                 cloth_cache_get_frame(clmd, framenr);
785                         }
786
787                         // Copy the result back to the object.
788                         cloth_to_object (ob, clmd, vertexCos, numverts);
789                         
790                         // bvh_free(clmd->clothObject->tree);
791                         // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
792                 } 
793
794         }
795         else if((deltaTime <= 0.0f)||(deltaTime > 1.0f))
796         {
797                 if(cloth_cache_search_frame(clmd, framenr))
798                 {
799                         cloth_cache_get_frame(clmd, framenr);
800                         cloth_to_object (ob, clmd, vertexCos, numverts);
801                 }
802         }
803 }
804
805 /* frees all */
806 void cloth_free_modifier (ClothModifierData *clmd)
807 {
808         Cloth   *cloth = NULL;
809
810         if(!clmd)
811                 return;
812
813         cloth = clmd->clothObject;
814
815         // free our frame cache
816         clmd->sim_parms.flags |= CSIMSETT_FLAG_CCACHE_FREE_ALL;
817         cloth_cache_free(clmd, 0);
818
819         if (cloth) 
820         {       
821                 // If our solver provides a free function, call it
822                 if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) 
823                 {       
824                         solvers [cloth->old_solver_type].free (clmd);
825                 }
826                 
827                 // Free the verts.
828                 if (cloth->verts != NULL)
829                         MEM_freeN (cloth->verts);
830
831                 cloth->verts = NULL;
832                 cloth->numverts = -1;
833                 
834                 // Free the springs.
835                 if (cloth->springs != NULL)
836                         MEM_freeN (cloth->springs);
837
838                 cloth->springs = NULL;
839                 cloth->numsprings = -1;         
840                 
841                 // free BVH collision tree
842                 if(cloth->tree)
843                         bvh_free((BVH *)cloth->tree);
844                 
845                 // we save our faces for collision objects
846                 if(cloth->mfaces)
847                         MEM_freeN(cloth->mfaces);
848         
849                 if(clmd->clothObject->facemarks)
850                         MEM_freeN(clmd->clothObject->facemarks);
851                 
852                 MEM_freeN (cloth);
853                 clmd->clothObject = NULL;
854         }
855 }
856
857
858 /******************************************************************************
859 *
860 * Internal functions.
861 *
862 ******************************************************************************/
863
864 /**
865 * cloth_to_object - copies the deformed vertices to the object.
866 *
867 * This function is a modified version of the softbody.c:softbody_to_object() function.
868 **/
869 static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts)
870 {
871         ClothVertex     *verts = NULL;
872         unsigned int    i = 0;
873
874         if (clmd->clothObject) {
875                 verts = clmd->clothObject->verts;
876
877                 /* inverse matrix is not uptodate... */
878                 Mat4Invert (ob->imat, ob->obmat);
879
880                 for (i = 0; i < numverts; i++, verts++)
881                 {
882                         VECCOPY (vertexCos[i], verts->x);
883                         Mat4MulVecfl (ob->imat, vertexCos[i]);  /* softbody is in global coords */
884                 }
885         }
886 }
887
888
889 /**
890 * cloth_apply_vgroup - applies a vertex group as specified by type
891 *
892 **/
893 static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup)
894 {
895         unsigned int i = 0;
896         unsigned int j = 0;
897         MDeformVert *dvert = NULL;
898         Cloth *clothObj = NULL;
899         unsigned int numverts = dm->getNumVerts(dm);
900         float goalfac = 0;
901         ClothVertex *verts = NULL;
902
903         clothObj = clmd->clothObject;
904         
905         if(!dm)
906                 return;
907         
908         numverts = dm->getNumVerts(dm);
909
910         /* vgroup is 1 based, decrement so we can match the right group. */
911         --vgroup;
912         
913         verts = clothObj->verts;
914
915         for (i = 0; i < numverts; i++, verts++)
916         {                                       
917                 // LATER ON, support also mass painting here
918                 if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) 
919                 {                                               
920                         dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
921                         if(dvert)       
922                         {               
923                                 for(j = 0; j < dvert->totweight; j++) 
924                                 {
925                                         if(dvert->dw[j].def_nr == vgroup) 
926                                         {
927                                                 verts->goal = dvert->dw [j].weight;
928
929                                                 goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal);
930                                                 verts->goal  = (float)pow(verts->goal , 4.0f);
931
932                                                 if(dvert->dw [j].weight >=SOFTGOALSNAP)
933                                                 {
934                                                         verts->flags |= CVERT_FLAG_PINNED;
935                                                 }
936
937                                                 // TODO enable mass painting here, for the moment i let "goals" go first
938
939                                                 break;
940                                         }
941                                 }
942                         }
943                 }
944         }
945 }
946
947 // only meshes supported at the moment
948 /* collision objects */
949 static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts)
950 {
951         unsigned int i;
952         MVert *mvert = NULL; 
953         ClothVertex *verts = NULL;
954         
955         /* If we have a clothObject, free it. */
956         if (clmd->clothObject != NULL)
957                 cloth_free_modifier (clmd);
958
959         /* Allocate a new cloth object. */
960         clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth");
961         if (clmd->clothObject) 
962         {
963                 clmd->clothObject->old_solver_type = -1;
964                 clmd->clothObject->old_collision_type = -1;
965         }
966         else if (clmd->clothObject == NULL) 
967         {
968                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
969                 return 0;
970         }
971
972         switch (ob->type)
973         {
974         case OB_MESH:
975                 
976                 // mesh input objects need DerivedMesh
977                 if(!dm)
978                         return 0;
979                 
980                 cloth_from_mesh (ob, clmd, dm);
981                 
982                 if (clmd->clothObject != NULL) 
983                 {
984                         mvert = CDDM_get_verts(dm);
985                         verts = clmd->clothObject->verts;
986                         
987                         for (i = 0; i < numverts; i++, verts++)
988                         {
989                                 VECCOPY (verts->x, mvert[i].co);
990                                 Mat4MulVecfl(ob->obmat, verts->x);
991                                 verts->flags = 0;
992                                 VECCOPY(verts->xold, verts->x);
993                                 VECCOPY(verts->txold, verts->x);
994                                 VECCOPY(verts->tx, verts->x);
995                                 VecMulf(verts->v, 0.0f);                                
996                         }
997                         clmd->clothObject->tree =  bvh_build(clmd,clmd->coll_parms.epsilon);
998                         
999                 }
1000
1001                 return 1;
1002         default: return 0; // TODO - we do not support changing meshes
1003         }
1004 }
1005
1006 /*
1007 helper function to get proper spring length 
1008 when object is rescaled
1009 */
1010 float cloth_globallen(float *v1,float *v2,Object *ob)
1011 {
1012         float p1[3],p2[3];
1013         VECCOPY(p1,v1);
1014         Mat4MulVecfl(ob->obmat, p1);    
1015         VECCOPY(p2,v2);
1016         Mat4MulVecfl(ob->obmat, p2);
1017         return VecLenf(p1,p2);
1018 }
1019
1020 static void curve_surf_to_cloth(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3])
1021 {
1022         Curve *cu= ob->data;
1023         Nurb *nu;
1024         BezTriple *bezt;
1025         float goalfac;
1026         unsigned int a, curindex=0, i=0;
1027         unsigned int numverts, numsprings = 0, setgoal=0;
1028         Cloth   *clothObj;
1029         ClothVertex *verts = NULL;
1030         
1031         clmd->clothObject->numverts = numverts= count_curveverts(&cu->nurb);
1032         clothObj = clmd->clothObject;
1033         
1034         if(ob->type==OB_CURVE) 
1035         {
1036                 numsprings = numverts - BLI_countlist(&cu->nurb);
1037         }
1038         
1039         /* Allocate our vertices.
1040         */
1041         clmd->clothObject->numverts = numverts;
1042         clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex");
1043         if (clmd->clothObject->verts == NULL) 
1044         {
1045                 cloth_free_modifier (clmd);
1046                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts.");
1047                 return;
1048         }
1049         
1050         verts = clmd->clothObject->verts;
1051         
1052         // copy vertex positions
1053         for (i = 0; i < numverts; i++)
1054         {
1055                 VECCOPY (verts->x, vertexCos[i]);
1056                 Mat4MulVecfl(ob->obmat, verts->x);
1057
1058                 verts->mass = clmd->sim_parms.mass;
1059                 // verts->goal= clmd->sim_parms.defgoal;
1060                 verts->flags = 0;
1061                 VECCOPY(verts->xold, verts->x);
1062                 VECCOPY(verts->xconst, verts->x);
1063                 VECCOPY(verts->txold, verts->x);
1064                 VecMulf(verts->v, 0.0f);
1065         }
1066         
1067         clmd->clothObject->mfaces = NULL; // update face pointer
1068         clmd->clothObject->numfaces = 0;
1069         
1070         clmd->clothObject->springs = MEM_callocN (sizeof (ClothSpring) * (numsprings), "cloth_springs_alloc");
1071                 
1072         // set vars now 
1073         goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal);
1074         // clothObj->verts [i].goal = clmd->sim_parms.mingoal + bezt->weight*goalfac;
1075         
1076         /* apply / set vertex groups */
1077         if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) 
1078         {
1079                 if (clmd->sim_parms.vgroup_mass > 0)
1080                 {
1081                         setgoal = 1;
1082                 }
1083         }
1084                 
1085 /*      
1086         for(nu= cu->nurb.first; nu; nu= nu->next) 
1087         {
1088                 if(nu->bezt) 
1089                 {
1090                         for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++, bp+=3, curindex+=3) 
1091                         {
1092                                 if(setgoal) 
1093                                 {
1094                                         bp->goal= sb->mingoal + bezt->weight*goalfac;
1095                                         // a little ad hoc changing the goal control to be less *sharp*
1096                                         bp->goal = (float)pow(bp->goal, 4.0f);
1097                                         
1098                                         // all three triples
1099                                         (bp+1)->goal= bp->goal;
1100                                         (bp+2)->goal= bp->goal;
1101                                 }
1102                                 
1103                                 if(totspring) 
1104                                 {
1105                                         if(a>0) 
1106                                         {
1107                                                 bs->v1= curindex-1;
1108                                                 bs->v2= curindex;
1109                                                 bs->strength= 1.0;
1110                                                 bs->order=1;
1111                                                 bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob );
1112                                                 bs++;
1113                                         }
1114                                         bs->v1= curindex;
1115                                         bs->v2= curindex+1;
1116                                         bs->strength= 1.0;
1117                                         bs->order=1;
1118                                         bs->len= globallen( bezt->vec[0], bezt->vec[1], ob );
1119                                         bs++;
1120                                         
1121                                         bs->v1= curindex+1;
1122                                         bs->v2= curindex+2;
1123                                         bs->strength= 1.0;
1124                                         bs->order=1;
1125                                         bs->len= globallen( bezt->vec[1], bezt->vec[2], ob );
1126                                         bs++;
1127                                 }
1128                         }
1129                 }
1130                 else {
1131                         for(bpnt=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bpnt++, bp++, curindex++) 
1132                         {
1133                                 if(setgoal) 
1134                                 {
1135                                         bp->goal= sb->mingoal + bpnt->weight*goalfac;
1136                                         // a little ad hoc changing the goal control to be less *sharp*
1137                                         bp->goal = (float)pow(bp->goal, 4.0f);
1138                                 }
1139                                 if(totspring && a>0) 
1140                                 {
1141                                         bs->v1= curindex-1;
1142                                         bs->v2= curindex;
1143                                         bs->strength= 1.0;
1144                                         bs->order=1;
1145                                         bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob );
1146                                         bs++;
1147                                 }
1148                         }
1149                 }
1150         }
1151         */
1152 }
1153                 
1154 // only meshes supported at the moment
1155 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts)
1156 {
1157         unsigned int i = 0;
1158         // dm->getNumVerts(dm);
1159         MVert *mvert = NULL; // CDDM_get_verts(dm);
1160         ClothVertex *verts = NULL;
1161         
1162         /* If we have a clothObject, free it. */
1163         if (clmd->clothObject != NULL)
1164                 cloth_free_modifier (clmd);
1165
1166         /* Allocate a new cloth object. */
1167         clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth");
1168         if (clmd->clothObject) 
1169         {
1170                 clmd->clothObject->old_solver_type = -1;
1171                 clmd->clothObject->old_collision_type = -1;
1172         }
1173         else if (clmd->clothObject == NULL) 
1174         {
1175                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
1176                 return 0;
1177         }
1178
1179         switch (ob->type)
1180         {
1181                 case OB_MESH:
1182                 
1183                 // mesh input objects need DerivedMesh
1184                 if(!dm)
1185                         return 0;
1186                 
1187                 cloth_from_mesh (ob, clmd, dm);
1188
1189                 if (clmd->clothObject != NULL) 
1190                 {                       
1191                         /* create springs */
1192                         clmd->clothObject->springs = NULL;
1193                         clmd->clothObject->numsprings = -1;
1194
1195                         if (!cloth_build_springs (clmd->clothObject, dm) )
1196                         {
1197                                 modifier_setError (&(clmd->modifier), "Can't build springs.");
1198                                 return 0;
1199                         }  
1200                         
1201                         mvert = CDDM_get_verts(dm);
1202                         verts = clmd->clothObject->verts;
1203
1204                         /* set initial values */
1205                         for (i = 0; i < numverts; i++, verts++)
1206                         {
1207                                 VECCOPY (verts->x, mvert[i].co);
1208                                 Mat4MulVecfl(ob->obmat, verts->x);
1209
1210                                 verts->mass = clmd->sim_parms.mass;
1211                                 
1212                                 if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) 
1213                                         verts->goal= clmd->sim_parms.defgoal;
1214                                 else
1215                                         verts->goal= 0.0f;
1216                                 
1217                                 verts->flags = 0;
1218                                 VECCOPY(verts->xold, verts->x);
1219                                 VECCOPY(verts->xconst, verts->x);
1220                                 VECCOPY(verts->txold, verts->x);
1221                                 VecMulf(verts->v, 0.0f);
1222                         }
1223
1224                         /* apply / set vertex groups */
1225                         if (clmd->sim_parms.vgroup_mass > 0)
1226                                 cloth_apply_vgroup (clmd, dm, clmd->sim_parms.vgroup_mass);
1227
1228                         /* init our solver */
1229                         if (solvers [clmd->sim_parms.solver_type].init)
1230                                 solvers [clmd->sim_parms.solver_type].init (ob, clmd);
1231
1232                         clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
1233
1234                         cloth_cache_set_frame(clmd, 1);
1235                 }
1236
1237                 return 1;
1238                 case OB_LATTICE:
1239                         printf("OB_LATTICE\n");
1240                 // lattice_to_softbody(ob);
1241                 return 1;
1242                 case OB_CURVE:
1243                 case OB_SURF:
1244                         printf("OB_SURF| OB_CURVE\n");
1245                 curve_surf_to_cloth(ob, clmd, vertexCos);
1246                 return 1;
1247                 default: return 0; // TODO - we do not support changing meshes
1248         }
1249         
1250         return 0;
1251 }
1252
1253 static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm)
1254 {
1255         unsigned int numverts = dm->getNumVerts(dm);
1256         unsigned int numfaces = dm->getNumFaces(dm);
1257         MFace *mface = CDDM_get_faces(dm);
1258         unsigned int i = 0;
1259
1260         /* Allocate our vertices.
1261         */
1262         clmd->clothObject->numverts = numverts;
1263         clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex");
1264         if (clmd->clothObject->verts == NULL) 
1265         {
1266                 cloth_free_modifier (clmd);
1267                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts.");
1268                 return;
1269         }
1270         
1271         // save face information
1272         clmd->clothObject->numfaces = numfaces;
1273         clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces");
1274         if (clmd->clothObject->mfaces == NULL) 
1275         {
1276                 cloth_free_modifier (clmd);
1277                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces.");
1278                 return;
1279         }
1280         for(i = 0; i < numfaces; i++)
1281                 memcpy(&clmd->clothObject->mfaces[i], &mface[i], sizeof(MFace));
1282
1283         
1284         // for SIP code
1285         // clmd->clothObject->facemarks = MEM_callocN (sizeof (unsigned char) * clmd->clothObject->numfaces, "clothFaceMarks");
1286
1287         /* Free the springs since they can't be correct if the vertices
1288         * changed.
1289         */
1290         if (clmd->clothObject->springs != NULL)
1291                 MEM_freeN (clmd->clothObject->springs);
1292
1293 }
1294
1295 /***************************************************************************************
1296 * SPRING NETWORK BUILDING IMPLEMENTATION BEGIN
1297 ***************************************************************************************/
1298
1299 int cloth_build_springs(Cloth *cloth, DerivedMesh *dm)
1300 {
1301         ClothSpring *springs = NULL;    
1302         unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
1303         unsigned int i = 0;
1304         unsigned int numverts = dm->getNumVerts(dm);
1305         unsigned int numedges = dm->getNumEdges(dm);
1306         unsigned int numfaces = dm->getNumFaces(dm);
1307         MVert *mvert = CDDM_get_verts(dm);
1308         MEdge *medge = CDDM_get_edges(dm);
1309         MFace *mface = CDDM_get_faces(dm);
1310         unsigned int index2 = 0; // our second vertex index
1311         LinkNode **edgelist = NULL;
1312         EdgeHash *edgehash = NULL;
1313         LinkNode *search = NULL;
1314         float temp[3];
1315         unsigned int temp_index = 0;
1316         ClothSpring *tspring = NULL;
1317
1318         // error handling
1319         if(numedges==0)
1320                 return 0;
1321
1322         edgelist = MEM_callocN (sizeof (LinkNode *) * numverts, "cloth_edgelist_alloc");
1323         for(i = 0; i < numverts; i++)
1324         {
1325                 edgelist[i] = NULL;
1326         }
1327
1328         if(cloth->springs)
1329                 MEM_freeN(cloth->springs);
1330
1331         // create spring network hash
1332         edgehash = BLI_edgehash_new();
1333
1334         // should be 4 for maximal bending springs, using 5 to be sure ;)
1335         springs = cloth->springs = MEM_callocN (sizeof (ClothSpring) * (numedges + numfaces * 2 +  6 * numverts), "cloth_springs_alloc");
1336
1337         // structural springs
1338         for(i = 0; i < numedges; i++)
1339         {
1340                 springs[i].ij = medge[i].v1;
1341                 springs[i].kl = medge[i].v2;
1342                 VECSUB(temp, mvert[springs[i].kl].co, mvert[springs[i].ij].co);
1343                 springs[i].restlen =  sqrt(INPR(temp, temp));
1344                 springs[i].type = STRUCTURAL;
1345                 springs[i].flags = 0;
1346                 struct_springs++;
1347         }
1348
1349         // shear springs
1350         for(i = 0; i < numfaces; i++)
1351         {
1352                 temp_index = struct_springs + shear_springs;
1353
1354                 springs[temp_index].ij = mface[i].v1;
1355                 springs[temp_index].kl = mface[i].v3;
1356                 VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co);
1357                 springs[temp_index].restlen =  sqrt(INPR(temp, temp));
1358                 springs[temp_index].type = SHEAR;
1359
1360                 BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index]));         
1361                 BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index]));
1362
1363                 shear_springs++;
1364                 temp_index++;
1365
1366                 springs[temp_index].ij = mface[i].v2;
1367                 springs[temp_index].kl = mface[i].v4;
1368                 VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co);
1369                 springs[temp_index].restlen =  sqrt(INPR(temp, temp));
1370                 springs[temp_index].type = SHEAR;
1371
1372                 BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index]));         
1373                 BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index]));
1374
1375                 shear_springs++;
1376         }
1377
1378         // bending springs
1379         for(i = struct_springs; i < struct_springs+shear_springs; i++)
1380         {       
1381                 search = edgelist[springs[i].kl];
1382                 while(search)
1383                 {
1384                         tspring = search->link;
1385                         index2 = ((tspring->ij==springs[i].kl) ? (tspring->kl) : (tspring->ij));
1386
1387                         if(!BLI_edgehash_haskey(edgehash, index2, springs[i].ij) // check for existing spring 
1388                                 && !BLI_edgehash_haskey(edgehash, springs[i].ij, index2)  // same
1389                                 && (index2!=springs[i].ij)) // check if startpoint is equal to endpoint
1390                         {
1391                                 temp_index = struct_springs + shear_springs + bend_springs;
1392
1393                                 springs[temp_index].ij = springs[i].ij;
1394                                 springs[temp_index].kl = index2;
1395                                 VECSUB(temp, mvert[index2].co, mvert[springs[i].ij].co);
1396                                 springs[temp_index].restlen =  sqrt(INPR(temp, temp));
1397                                 springs[temp_index].type = BENDING;
1398                                 BLI_edgehash_insert(edgehash, springs[temp_index].ij, index2, NULL);
1399                                 bend_springs++;
1400
1401                         }
1402                         search = search->next;   
1403                 }
1404         }
1405
1406         cloth->numsprings = struct_springs + shear_springs + bend_springs;
1407
1408         for(i = 0; i < numverts; i++)
1409         {
1410                 BLI_linklist_free(edgelist[i],NULL); 
1411         }
1412         if(edgelist)
1413                 MEM_freeN(edgelist);    
1414
1415         BLI_edgehash_free(edgehash, NULL);
1416
1417         return 1;
1418
1419 } /* cloth_build_springs */
1420 /***************************************************************************************
1421 * SPRING NETWORK BUILDING IMPLEMENTATION END
1422 ***************************************************************************************/
1423