Merge with trunk: svn merge -r 12182:12207 https://svn.blender.org/svnroot/bf-blender...
[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         
408         if(clmd->clothObject)
409         {
410                 search = clmd->sim_parms.cache;
411                 
412                 while(search)
413                 {
414                         frame = (Frame *)search->link;
415                         
416                         if(frame)
417                         {
418                                 if(frame->time == time)
419                                         return 1;
420                         }
421                         
422                         search = search->next;
423                 }
424         }
425         
426         return 0;
427         
428 }
429
430 float cloth_cache_last_frame(ClothModifierData *clmd)
431 {
432         Frame *frame = NULL;
433         LinkNode *search = NULL;        
434         float time = 0;
435         
436         if(clmd->clothObject)
437         {
438                 search = clmd->sim_parms.cache;
439                 
440                 while(search)
441                 {
442                         frame = (Frame *)search->link;
443                         
444                         if(frame)
445                         {
446                                 if(frame->time > time)
447                                         time = frame->time;
448                         }
449                 }
450         }
451         return time;
452 }
453
454 float cloth_cache_first_frame(ClothModifierData *clmd)
455 {
456         Frame *frame = NULL;
457         LinkNode *search = NULL;        
458         float time = -1.0;
459         
460         if(clmd->clothObject)
461         {
462                 search = clmd->sim_parms.cache;
463                 
464                 while(search)
465                 {
466                         frame = (Frame *)search->link;
467                         
468                         if(frame)
469                         {
470                                 if(time < 0.0)
471                                         time = frame->time;
472                                 else
473                                 {
474                                         if(frame->time < time)
475                                                 time = frame->time;
476                                 }
477                         }
478                 }
479         }
480         return time;
481 }
482
483 void cloth_cache_get_frame(ClothModifierData *clmd, float time)
484 {
485         Frame *frame = NULL;
486         LinkNode *search = NULL;
487         float newtime = time + clmd->sim_parms.preroll; 
488         
489         if(clmd->clothObject)
490         {
491                 search = clmd->sim_parms.cache;
492                 
493                 while(search)
494                 {
495                         frame = (Frame *)search->link;
496                         
497                         if(frame)
498                         {
499                                 if(frame->time == newtime)
500                                 {
501                                         // something changed, free cache!
502                                         if(clmd->clothObject->numverts != frame->numverts)
503                                         {
504                                                 cloth_cache_free(clmd, 0);
505                                                 printf("clmd->clothObject->numverts != frame->numverts\n");
506                                                 return;
507                                         }
508                                         
509                                         memcpy(clmd->clothObject->verts, frame->verts, sizeof(ClothVertex)*frame->numverts);
510                                         implicit_set_positions(clmd);
511                                         
512                                         return;
513                                 }
514                         }
515                         
516                         search = search->next;
517                 }
518         }
519 }
520
521 void cloth_cache_set_frame(ClothModifierData *clmd, float time)
522 {
523         Frame *frame = NULL;
524         LinkNode *search = NULL;
525         
526         if(clmd->clothObject)
527         {
528                 frame = (Frame *)MEM_callocN (sizeof (Frame), "cloth_cache_frame");
529                 
530                 if(frame)
531                 {
532                         frame->time = time;
533                         frame->numverts = clmd->clothObject->numverts;
534                         frame->verts = MEM_dupallocN(clmd->clothObject->verts); 
535                         
536                         if(!frame->verts)
537                         {
538                                 MEM_freeN(frame);
539                                 return;
540                         }
541                         
542                         BLI_linklist_append(&clmd->sim_parms.cache, frame);
543                         
544                 }
545         }       
546         
547 }
548
549 // free cloth cache
550 void cloth_cache_free(ClothModifierData *clmd, float time)
551 {
552         Frame *frame = NULL;
553         LinkNode *search = NULL, *lastsearch = NULL;    
554         float newtime = time + clmd->sim_parms.preroll;
555         
556         if(time <= 2.0)
557                 newtime = time;
558
559         if(clmd->clothObject)
560         {
561                 if(clmd->sim_parms.cache)
562                 {       
563                         lastsearch = search = clmd->sim_parms.cache;
564                         
565                         while(search)
566                         {
567                                 frame = (Frame *)search->link;
568                                 
569                                 if(frame->time >= newtime)
570                                 {
571                                         if(frame->verts)
572                                         {
573                                                 MEM_freeN(frame->verts);
574                                         }
575                                         MEM_freeN(frame);
576                                         
577                                         lastsearch->next = search->next;
578                                         MEM_freeN(search);
579                                         search = lastsearch->next;
580                                         lastsearch->next = NULL;
581                                 }
582                                 else
583                                 {
584                                         lastsearch = search;
585                                         search = search->next;
586                                 }
587                         }
588                         
589                         if(time <= 1.0)
590                         {
591                                 clmd->sim_parms.cache = NULL;
592                         }
593                         
594                         if(time <= 2.0) 
595                                 clmd->sim_parms.preroll = 0;
596                 }
597         }
598 }
599
600
601 /**
602 * cloth_deform_verts - simulates one step, framenr is in frames.
603
604 **/
605 void clothModifier_do(ClothModifierData *clmd, Object *ob, DerivedMesh *dm,
606                 float (*vertexCos)[3], int numverts)
607 {
608         unsigned int i;
609         unsigned int numedges = -1;
610         unsigned int numfaces = -1;
611         MVert *mvert = NULL;
612         MEdge *medge = NULL;
613         MFace *mface = NULL;
614         DerivedMesh *result = NULL, *result2 = NULL;
615         Cloth *cloth = clmd->clothObject;
616         unsigned int framenr = (float)G.scene->r.cfra;
617         float current_time = bsystem_time(ob, (float)G.scene->r.cfra, 0.0);
618         ListBase        *effectors = NULL;
619         ClothVertex *newframe= NULL, *verts;
620         Frame *frame = NULL;
621         LinkNode *search = NULL;
622         float deltaTime = current_time - clmd->sim_parms.sim_time;      
623                 
624         
625         // only be active during a specific period:
626         // that's "first frame" and "last frame" on GUI
627         if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ))
628         {
629                 if(clmd->clothObject)
630                 {
631                         if(clmd->sim_parms.cache)
632                         {
633                                 if(current_time < clmd->sim_parms.firstframe)
634                                 {
635                                         int frametime = cloth_cache_first_frame(clmd);
636                                         if(cloth_cache_search_frame(clmd, frametime))
637                                         {
638                                                 cloth_cache_get_frame(clmd, frametime);
639                                                 cloth_to_object (ob, clmd, vertexCos, numverts);
640                                         }
641                                         return;
642                                 }
643                                 else if(current_time > clmd->sim_parms.lastframe)
644                                 {
645                                         int frametime = cloth_cache_last_frame(clmd);
646                                         if(cloth_cache_search_frame(clmd, frametime))
647                                         {
648                                                 cloth_cache_get_frame(clmd, frametime);
649                                                 cloth_to_object (ob, clmd, vertexCos, numverts);
650                                         }
651                                         return;
652                                 }
653                                 else if(ABS(deltaTime) >= 2.0f ) // no timewarps allowed
654                                 {
655                                         if(cloth_cache_search_frame(clmd, framenr))
656                                         {
657                                                 cloth_cache_get_frame(clmd, framenr);
658                                                 cloth_to_object (ob, clmd, vertexCos, numverts);
659                                         }
660                                         clmd->sim_parms.sim_time = current_time;
661                                         return;
662                                 }
663                         }
664                         
665                 }
666         }
667         
668         
669         // unused in the moment, calculated seperately in implicit.c
670         clmd->sim_parms.dt = 1.0f / clmd->sim_parms.stepsPerFrame;
671         
672         clmd->sim_parms.sim_time = current_time;
673         
674         // check if cloth object was some collision object before and needs freeing now
675         if (!(clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ) && (clmd->clothObject != NULL) && (clmd->clothObject->old_solver_type == 255))
676         {
677                 // temporary set CSIMSETT_FLAG_COLLOBJ flag for proper freeing 
678                 clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ;
679                 cloth_free_modifier(clmd);
680                 clmd->sim_parms.flags &= ~CSIMSETT_FLAG_COLLOBJ;
681         }
682
683         // This is for collisions objects: check special case CSIMSETT_FLAG_COLLOBJ
684         if (clmd->sim_parms.flags & CSIMSETT_FLAG_COLLOBJ)
685         {
686                 // save next position + time            
687                 if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) )
688                 {
689                         if(!collobj_from_object (ob, clmd, dm, vertexCos, framenr))
690                         {
691                                 clmd->sim_parms.flags |= CSIMSETT_FLAG_COLLOBJ;
692                                 cloth_free_modifier(clmd);
693                                 return;
694                         }
695
696                         if(clmd->clothObject == NULL)
697                                 return;
698
699                         cloth = clmd->clothObject;
700                 }
701
702                 // Save old position 
703                 clmd->sim_parms.sim_time_old = clmd->sim_parms.sim_time;
704                 clmd->sim_parms.sim_time = current_time; 
705                 
706                 verts = cloth->verts;
707                 
708                 for (i = 0; i < clmd->clothObject->numverts; i++, verts++)
709                 {
710                         // Save the previous position. 
711                         VECCOPY (verts->xold, verts->x);
712                         VECCOPY (verts->txold, verts->x);
713
714                         // Get the current position. 
715                         VECCOPY (verts->x, vertexCos[i]);
716                         Mat4MulVecfl(ob->obmat, verts->x);
717
718                         // Compute the vertices "velocity".
719                         // (no dt correction here because of float error)
720                         VECSUB (verts->v, verts->x, verts->xold);
721                 }
722                 
723                 return;
724         }       
725
726         if(deltaTime == 1.0f)
727         {
728                 if ((clmd->clothObject == NULL) || (numverts != clmd->clothObject->numverts) ) 
729                 {
730                         if(!cloth_from_object (ob, clmd, dm, vertexCos, numverts))
731                                 return;
732
733                         if(clmd->clothObject == NULL)
734                                 return;
735
736                         cloth = clmd->clothObject;
737                 }
738
739                 clmd->clothObject->old_solver_type = clmd->sim_parms.solver_type;
740
741                 // Insure we have a clmd->clothObject, in case allocation failed.
742                 if (clmd->clothObject != NULL) 
743                 {            
744                         if(!cloth_cache_search_frame(clmd, framenr))
745                         {
746                                 verts = cloth->verts;
747                                 
748                                 // Force any pinned verts to their constrained location. 
749                                 for (i = 0; i < clmd->clothObject->numverts; i++, verts++)
750                                 {
751                                         // Save the previous position. 
752                                         VECCOPY (verts->xold, verts->xconst);
753                                         VECCOPY (verts->txold, verts->x);
754
755                                         // Get the current position. 
756                                         VECCOPY (verts->xconst, vertexCos[i]);
757                                         Mat4MulVecfl(ob->obmat, verts->xconst);
758                                 }
759
760                                 tstart();
761
762                                 // Call the solver.
763                                 if (solvers [clmd->sim_parms.solver_type].solver)
764                                         solvers [clmd->sim_parms.solver_type].solver (ob, framenr, clmd, effectors);
765                                 
766                                 tend();
767                                 printf("Cloth simulation time: %f\n", (float)tval());
768
769                                 cloth_cache_set_frame(clmd, framenr);
770
771                         }
772                         else // just retrieve the cached frame
773                         {
774                                 cloth_cache_get_frame(clmd, framenr);
775                         }
776
777                         // Copy the result back to the object.
778                         cloth_to_object (ob, clmd, vertexCos, numverts);
779                         
780                         // bvh_free(clmd->clothObject->tree);
781                         // clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
782                 } 
783
784         }
785         else if((deltaTime <= 0.0f)||(deltaTime > 1.0f))
786         {
787                 if((clmd->clothObject != NULL) && (clmd->sim_parms.cache)) 
788                 {
789                         if(cloth_cache_search_frame(clmd, framenr))
790                         {
791                                 cloth_cache_get_frame(clmd, framenr);
792                                 cloth_to_object (ob, clmd, vertexCos, numverts);
793                         }
794                 }
795         }
796         
797 }
798
799 /* frees all */
800 void cloth_free_modifier (ClothModifierData *clmd)
801 {
802         Cloth   *cloth = NULL;
803
804         if(!clmd)
805                 return;
806
807         cloth = clmd->clothObject;
808         
809         if(!(clmd->sim_parms.flags & CSIMSETT_FLAG_CCACHE_PROTECT))
810         {
811                 // free our frame cache, TODO: but get to first position before
812                 cloth_cache_free(clmd, 0);
813         
814                 if (cloth) 
815                 {       
816                         // If our solver provides a free function, call it
817                         if (cloth->old_solver_type < 255 && solvers [cloth->old_solver_type].free) 
818                         {       
819                                 solvers [cloth->old_solver_type].free (clmd);
820                         }
821                         
822                         // Free the verts.
823                         if (cloth->verts != NULL)
824                                 MEM_freeN (cloth->verts);
825         
826                         cloth->verts = NULL;
827                         cloth->numverts = 0;
828                         
829                         // Free the springs.
830                         if (cloth->springs != NULL)
831                                 MEM_freeN (cloth->springs);
832         
833                         cloth->springs = NULL;
834                         cloth->numsprings = 0;  
835                         
836                         // free BVH collision tree
837                         if(cloth->tree)
838                                 bvh_free((BVH *)cloth->tree);
839                         
840                         // we save our faces for collision objects
841                         if(cloth->mfaces)
842                                 MEM_freeN(cloth->mfaces);
843                         /*
844                         if(clmd->clothObject->facemarks)
845                                 MEM_freeN(clmd->clothObject->facemarks);
846                         */
847                         MEM_freeN (cloth);
848                         clmd->clothObject = NULL;
849                 }
850         }
851 }
852
853
854 /******************************************************************************
855 *
856 * Internal functions.
857 *
858 ******************************************************************************/
859
860 /**
861 * cloth_to_object - copies the deformed vertices to the object.
862 *
863 * This function is a modified version of the softbody.c:softbody_to_object() function.
864 **/
865 static void cloth_to_object (Object *ob, ClothModifierData *clmd, float (*vertexCos)[3], unsigned int numverts)
866 {
867         ClothVertex     *verts = NULL;
868         unsigned int    i = 0;
869
870         if (clmd->clothObject) {
871                 verts = clmd->clothObject->verts;
872
873                 /* inverse matrix is not uptodate... */
874                 Mat4Invert (ob->imat, ob->obmat);
875
876                 for (i = 0; i < numverts; i++, verts++)
877                 {
878                         VECCOPY (vertexCos[i], verts->x);
879                         Mat4MulVecfl (ob->imat, vertexCos[i]);  /* softbody is in global coords */
880                 }
881         }
882 }
883
884
885 /**
886 * cloth_apply_vgroup - applies a vertex group as specified by type
887 *
888 **/
889 static void cloth_apply_vgroup(ClothModifierData *clmd, DerivedMesh *dm, short vgroup)
890 {
891         unsigned int i = 0;
892         unsigned int j = 0;
893         MDeformVert *dvert = NULL;
894         Cloth *clothObj = NULL;
895         unsigned int numverts = dm->getNumVerts(dm);
896         float goalfac = 0;
897         ClothVertex *verts = NULL;
898
899         clothObj = clmd->clothObject;
900         
901         if(!dm)
902                 return;
903         
904         numverts = dm->getNumVerts(dm);
905
906         /* vgroup is 1 based, decrement so we can match the right group. */
907         --vgroup;
908         
909         verts = clothObj->verts;
910
911         for (i = 0; i < numverts; i++, verts++)
912         {                                       
913                 // LATER ON, support also mass painting here
914                 if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) 
915                 {                                               
916                         dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
917                         if(dvert)       
918                         {               
919                                 for(j = 0; j < dvert->totweight; j++) 
920                                 {
921                                         if(dvert->dw[j].def_nr == vgroup) 
922                                         {
923                                                 verts->goal = dvert->dw [j].weight;
924
925                                                 goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal);
926                                                 verts->goal  = (float)pow(verts->goal , 4.0f);
927
928                                                 if(dvert->dw [j].weight >=SOFTGOALSNAP)
929                                                 {
930                                                         verts->flags |= CVERT_FLAG_PINNED;
931                                                 }
932
933                                                 // TODO enable mass painting here, for the moment i let "goals" go first
934
935                                                 break;
936                                         }
937                                 }
938                         }
939                 }
940         }
941 }
942
943 // only meshes supported at the moment
944 /* collision objects */
945 static int collobj_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts)
946 {
947         unsigned int i;
948         MVert *mvert = NULL; 
949         ClothVertex *verts = NULL;
950         float tnull[3] = {0,0,0}; 
951         
952         /* If we have a clothObject, free it. */
953         if (clmd->clothObject != NULL)
954                 cloth_free_modifier (clmd);
955
956         /* Allocate a new cloth object. */
957         clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth");
958         if (clmd->clothObject) 
959         {
960                 clmd->clothObject->old_solver_type = 255;
961                 clmd->clothObject->old_collision_type = 255;
962         }
963         else if (clmd->clothObject == NULL) 
964         {
965                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
966                 return 0;
967         }
968
969         switch (ob->type)
970         {
971         case OB_MESH:
972                 
973                 // mesh input objects need DerivedMesh
974                 if(!dm)
975                         return 0;
976                 
977                 cloth_from_mesh (ob, clmd, dm);
978                 
979                 if (clmd->clothObject != NULL) 
980                 {
981                         if (!dm) return 0;
982                         if (!dm->getNumVerts(dm) || !dm->getNumFaces(dm)) return 0;
983                         
984                         mvert = dm->getVertArray(dm);
985                         verts = clmd->clothObject->verts;
986                         numverts = clmd->clothObject->numverts = dm->getNumVerts(dm);
987                         
988                         for (i = 0; i < numverts; i++, verts++)
989                         {
990                                 VECCOPY (verts->x, mvert[i].co);
991                                 Mat4MulVecfl(ob->obmat, verts->x);
992                                 verts->flags = 0;
993                                 VECCOPY(verts->xold, verts->x);
994                                 VECCOPY(verts->txold, verts->x);
995                                 VECCOPY(verts->tx, verts->x);
996                                 VecMulf(verts->v, 0.0f);
997                                 verts->impulse_count = 0;
998                                 VECCOPY(verts->impulse, tnull);
999                         }
1000                         clmd->clothObject->tree =  bvh_build(clmd,clmd->coll_parms.epsilon);
1001                         
1002                 }
1003                 
1004                 return 1;
1005         default: return 0; // TODO - we do not support changing meshes
1006         }
1007 }
1008
1009 /*
1010 helper function to get proper spring length 
1011 when object is rescaled
1012 */
1013 float cloth_globallen(float *v1,float *v2,Object *ob)
1014 {
1015         float p1[3],p2[3];
1016         VECCOPY(p1,v1);
1017         Mat4MulVecfl(ob->obmat, p1);    
1018         VECCOPY(p2,v2);
1019         Mat4MulVecfl(ob->obmat, p2);
1020         return VecLenf(p1,p2);
1021 }
1022
1023 static void curve_surf_to_cloth(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3])
1024 {
1025         Curve *cu= ob->data;
1026         Nurb *nu;
1027         BezTriple *bezt;
1028         float goalfac;
1029         unsigned int a, curindex=0, i=0;
1030         unsigned int numverts, numsprings = 0, setgoal=0;
1031         Cloth   *clothObj;
1032         ClothVertex *verts = NULL;
1033         
1034         clmd->clothObject->numverts = numverts= count_curveverts(&cu->nurb);
1035         clothObj = clmd->clothObject;
1036         
1037         if(ob->type==OB_CURVE) 
1038         {
1039                 numsprings = numverts - BLI_countlist(&cu->nurb);
1040         }
1041         
1042         /* Allocate our vertices.
1043         */
1044         clmd->clothObject->numverts = numverts;
1045         clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex");
1046         if (clmd->clothObject->verts == NULL) 
1047         {
1048                 cloth_free_modifier (clmd);
1049                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts.");
1050                 return;
1051         }
1052         
1053         verts = clmd->clothObject->verts;
1054         
1055         // copy vertex positions
1056         for (i = 0; i < numverts; i++)
1057         {
1058                 VECCOPY (verts->x, vertexCos[i]);
1059                 Mat4MulVecfl(ob->obmat, verts->x);
1060
1061                 verts->mass = clmd->sim_parms.mass;
1062                 // verts->goal= clmd->sim_parms.defgoal;
1063                 verts->flags = 0;
1064                 VECCOPY(verts->xold, verts->x);
1065                 VECCOPY(verts->xconst, verts->x);
1066                 VECCOPY(verts->txold, verts->x);
1067                 VecMulf(verts->v, 0.0f);
1068         }
1069         
1070         clmd->clothObject->mfaces = NULL; // update face pointer
1071         clmd->clothObject->numfaces = 0;
1072         
1073         clmd->clothObject->springs = MEM_callocN (sizeof (ClothSpring) * (numsprings), "cloth_springs_alloc");
1074                 
1075         // set vars now 
1076         goalfac= ABS(clmd->sim_parms.maxgoal - clmd->sim_parms.mingoal);
1077         // clothObj->verts [i].goal = clmd->sim_parms.mingoal + bezt->weight*goalfac;
1078         
1079         /* apply / set vertex groups */
1080         if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) 
1081         {
1082                 if (clmd->sim_parms.vgroup_mass > 0)
1083                 {
1084                         setgoal = 1;
1085                 }
1086         }
1087                 
1088 /*      
1089         for(nu= cu->nurb.first; nu; nu= nu->next) 
1090         {
1091                 if(nu->bezt) 
1092                 {
1093                         for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++, bp+=3, curindex+=3) 
1094                         {
1095                                 if(setgoal) 
1096                                 {
1097                                         bp->goal= sb->mingoal + bezt->weight*goalfac;
1098                                         // a little ad hoc changing the goal control to be less *sharp*
1099                                         bp->goal = (float)pow(bp->goal, 4.0f);
1100                                         
1101                                         // all three triples
1102                                         (bp+1)->goal= bp->goal;
1103                                         (bp+2)->goal= bp->goal;
1104                                 }
1105                                 
1106                                 if(totspring) 
1107                                 {
1108                                         if(a>0) 
1109                                         {
1110                                                 bs->v1= curindex-1;
1111                                                 bs->v2= curindex;
1112                                                 bs->strength= 1.0;
1113                                                 bs->order=1;
1114                                                 bs->len= globallen( (bezt-1)->vec[2], bezt->vec[0], ob );
1115                                                 bs++;
1116                                         }
1117                                         bs->v1= curindex;
1118                                         bs->v2= curindex+1;
1119                                         bs->strength= 1.0;
1120                                         bs->order=1;
1121                                         bs->len= globallen( bezt->vec[0], bezt->vec[1], ob );
1122                                         bs++;
1123                                         
1124                                         bs->v1= curindex+1;
1125                                         bs->v2= curindex+2;
1126                                         bs->strength= 1.0;
1127                                         bs->order=1;
1128                                         bs->len= globallen( bezt->vec[1], bezt->vec[2], ob );
1129                                         bs++;
1130                                 }
1131                         }
1132                 }
1133                 else {
1134                         for(bpnt=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bpnt++, bp++, curindex++) 
1135                         {
1136                                 if(setgoal) 
1137                                 {
1138                                         bp->goal= sb->mingoal + bpnt->weight*goalfac;
1139                                         // a little ad hoc changing the goal control to be less *sharp*
1140                                         bp->goal = (float)pow(bp->goal, 4.0f);
1141                                 }
1142                                 if(totspring && a>0) 
1143                                 {
1144                                         bs->v1= curindex-1;
1145                                         bs->v2= curindex;
1146                                         bs->strength= 1.0;
1147                                         bs->order=1;
1148                                         bs->len= globallen( (bpnt-1)->vec, bpnt->vec , ob );
1149                                         bs++;
1150                                 }
1151                         }
1152                 }
1153         }
1154         */
1155 }
1156                 
1157 // only meshes supported at the moment
1158 static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *dm, float (*vertexCos)[3], unsigned int numverts)
1159 {
1160         unsigned int i = 0;
1161         // dm->getNumVerts(dm);
1162         MVert *mvert = NULL; // CDDM_get_verts(dm);
1163         ClothVertex *verts = NULL;
1164         float tnull[3] = {0,0,0};
1165         
1166         /* If we have a clothObject, free it. */
1167         if (clmd->clothObject != NULL)
1168                 cloth_free_modifier (clmd);
1169
1170         /* Allocate a new cloth object. */
1171         clmd->clothObject = MEM_callocN (sizeof(Cloth), "cloth");
1172         if (clmd->clothObject) 
1173         {
1174                 clmd->clothObject->old_solver_type = 255;
1175                 clmd->clothObject->old_collision_type = 255;
1176         }
1177         else if (clmd->clothObject == NULL) 
1178         {
1179                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject.");
1180                 return 0;
1181         }
1182
1183         switch (ob->type)
1184         {
1185                 case OB_MESH:
1186                 
1187                 // mesh input objects need DerivedMesh
1188                 if(!dm)
1189                         return 0;
1190                 
1191                 cloth_from_mesh (ob, clmd, dm);
1192
1193                 if (clmd->clothObject != NULL) 
1194                 {                       
1195                         /* create springs */
1196                         clmd->clothObject->springs = NULL;
1197                         clmd->clothObject->numsprings = -1;
1198
1199                         if (!cloth_build_springs (clmd->clothObject, dm) )
1200                         {
1201                                 modifier_setError (&(clmd->modifier), "Can't build springs.");
1202                                 return 0;
1203                         }  
1204                         
1205                         mvert = CDDM_get_verts(dm);
1206                         verts = clmd->clothObject->verts;
1207
1208                         /* set initial values */
1209                         for (i = 0; i < numverts; i++, verts++)
1210                         {
1211                                 VECCOPY (verts->x, mvert[i].co);
1212                                 Mat4MulVecfl(ob->obmat, verts->x);
1213
1214                                 verts->mass = clmd->sim_parms.mass;
1215                                 
1216                                 if(clmd->sim_parms.flags & CSIMSETT_FLAG_GOAL) 
1217                                         verts->goal= clmd->sim_parms.defgoal;
1218                                 else
1219                                         verts->goal= 0.0f;
1220                                 
1221                                 verts->flags = 0;
1222                                 VECCOPY(verts->xold, verts->x);
1223                                 VECCOPY(verts->xconst, verts->x);
1224                                 VECCOPY(verts->txold, verts->x);
1225                                 VecMulf(verts->v, 0.0f);
1226                                 
1227                                 verts->impulse_count = 0;
1228                                 VECCOPY(verts->impulse, tnull);
1229                         }
1230
1231                         // apply / set vertex groups 
1232                         if (clmd->sim_parms.vgroup_mass > 0)
1233                                 cloth_apply_vgroup (clmd, dm, clmd->sim_parms.vgroup_mass);
1234
1235                         // init our solver
1236                         if (solvers [clmd->sim_parms.solver_type].init)
1237                                 solvers [clmd->sim_parms.solver_type].init (ob, clmd);
1238
1239                         clmd->clothObject->tree = bvh_build(clmd, clmd->coll_parms.epsilon);
1240
1241                         cloth_cache_set_frame(clmd, 1);
1242                 }
1243
1244                 return 1;
1245                 case OB_LATTICE:
1246                         printf("OB_LATTICE\n");
1247                 // lattice_to_softbody(ob);
1248                 return 1;
1249                 case OB_CURVE:
1250                 case OB_SURF:
1251                         printf("OB_SURF| OB_CURVE\n");
1252                 curve_surf_to_cloth(ob, clmd, vertexCos);
1253                 return 1;
1254                 default: return 0; // TODO - we do not support changing meshes
1255         }
1256         
1257         return 0;
1258 }
1259
1260 static void cloth_from_mesh (Object *ob, ClothModifierData *clmd, DerivedMesh *dm)
1261 {
1262         unsigned int numverts = dm->getNumVerts(dm);
1263         unsigned int numfaces = dm->getNumFaces(dm);
1264         MFace *mface = dm->getFaceArray(dm);
1265         unsigned int i = 0;
1266
1267         /* Allocate our vertices.
1268         */
1269         clmd->clothObject->numverts = numverts;
1270         clmd->clothObject->verts = MEM_callocN (sizeof (ClothVertex) * clmd->clothObject->numverts, "clothVertex");
1271         if (clmd->clothObject->verts == NULL) 
1272         {
1273                 cloth_free_modifier (clmd);
1274                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts.");
1275                 return;
1276         }
1277         
1278         // save face information
1279         clmd->clothObject->numfaces = numfaces;
1280         clmd->clothObject->mfaces = MEM_callocN (sizeof (MFace) * clmd->clothObject->numfaces, "clothMFaces");
1281         if (clmd->clothObject->mfaces == NULL) 
1282         {
1283                 cloth_free_modifier (clmd);
1284                 modifier_setError (&(clmd->modifier), "Out of memory on allocating clmd->clothObject->mfaces.");
1285                 return;
1286         }
1287         for(i = 0; i < numfaces; i++)
1288                 memcpy(&clmd->clothObject->mfaces[i], &mface[i], sizeof(MFace));
1289
1290         
1291         // for SIP code
1292         // clmd->clothObject->facemarks = MEM_callocN (sizeof (unsigned char) * clmd->clothObject->numfaces, "clothFaceMarks");
1293
1294         /* Free the springs since they can't be correct if the vertices
1295         * changed.
1296         */
1297         if (clmd->clothObject->springs != NULL)
1298                 MEM_freeN (clmd->clothObject->springs);
1299
1300 }
1301
1302 /***************************************************************************************
1303 * SPRING NETWORK BUILDING IMPLEMENTATION BEGIN
1304 ***************************************************************************************/
1305
1306 int cloth_build_springs(Cloth *cloth, DerivedMesh *dm)
1307 {
1308         ClothSpring *springs = NULL;    
1309         unsigned int struct_springs = 0, shear_springs=0, bend_springs = 0;
1310         unsigned int i = 0;
1311         unsigned int numverts = dm->getNumVerts(dm);
1312         unsigned int numedges = dm->getNumEdges(dm);
1313         unsigned int numfaces = dm->getNumFaces(dm);
1314         MVert *mvert = CDDM_get_verts(dm);
1315         MEdge *medge = CDDM_get_edges(dm);
1316         MFace *mface = CDDM_get_faces(dm);
1317         unsigned int index2 = 0; // our second vertex index
1318         LinkNode **edgelist = NULL;
1319         EdgeHash *edgehash = NULL;
1320         LinkNode *search = NULL;
1321         float temp[3];
1322         unsigned int temp_index = 0;
1323         ClothSpring *tspring = NULL;
1324
1325         // error handling
1326         if(numedges==0)
1327                 return 0;
1328
1329         edgelist = MEM_callocN (sizeof (LinkNode *) * numverts, "cloth_edgelist_alloc");
1330         for(i = 0; i < numverts; i++)
1331         {
1332                 edgelist[i] = NULL;
1333         }
1334
1335         if(cloth->springs)
1336                 MEM_freeN(cloth->springs);
1337
1338         // create spring network hash
1339         edgehash = BLI_edgehash_new();
1340
1341         // should be 4 for maximal bending springs, using 5 to be sure ;)
1342         springs = cloth->springs = MEM_callocN (sizeof (ClothSpring) * (numedges + numfaces * 2 +  6 * numverts), "cloth_springs_alloc");
1343
1344         // structural springs
1345         for(i = 0; i < numedges; i++)
1346         {
1347                 springs[i].ij = medge[i].v1;
1348                 springs[i].kl = medge[i].v2;
1349                 VECSUB(temp, mvert[springs[i].kl].co, mvert[springs[i].ij].co);
1350                 springs[i].restlen =  sqrt(INPR(temp, temp));
1351                 springs[i].type = STRUCTURAL;
1352                 springs[i].flags = 0;
1353                 struct_springs++;
1354         }
1355
1356         // shear springs
1357         for(i = 0; i < numfaces; i++)
1358         {
1359                 temp_index = struct_springs + shear_springs;
1360
1361                 springs[temp_index].ij = mface[i].v1;
1362                 springs[temp_index].kl = mface[i].v3;
1363                 VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co);
1364                 springs[temp_index].restlen =  sqrt(INPR(temp, temp));
1365                 springs[temp_index].type = SHEAR;
1366
1367                 BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index]));         
1368                 BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index]));
1369
1370                 shear_springs++;
1371                 temp_index++;
1372                 
1373                 if(mface[i].v4)
1374                 {
1375                         springs[temp_index].ij = mface[i].v2;
1376                         springs[temp_index].kl = mface[i].v4;
1377                         VECSUB(temp, mvert[springs[temp_index].kl].co, mvert[springs[temp_index].ij].co);
1378                         springs[temp_index].restlen =  sqrt(INPR(temp, temp));
1379                         springs[temp_index].type = SHEAR;
1380         
1381                         BLI_linklist_append(&edgelist[springs[temp_index].ij], &(springs[temp_index]));
1382                         BLI_linklist_append(&edgelist[springs[temp_index].kl], &(springs[temp_index]));
1383         
1384                         shear_springs++;
1385                 }
1386         }
1387
1388         // bending springs
1389         for(i = struct_springs; i < struct_springs+shear_springs; i++)
1390         {       
1391                 search = edgelist[springs[i].kl];
1392                 while(search)
1393                 {
1394                         tspring = search->link;
1395                         index2 = ((tspring->ij==springs[i].kl) ? (tspring->kl) : (tspring->ij));
1396
1397                         if(!BLI_edgehash_haskey(edgehash, index2, springs[i].ij) // check for existing spring 
1398                                 && !BLI_edgehash_haskey(edgehash, springs[i].ij, index2)  // same
1399                                 && (index2!=springs[i].ij)) // check if startpoint is equal to endpoint
1400                         {
1401                                 temp_index = struct_springs + shear_springs + bend_springs;
1402
1403                                 springs[temp_index].ij = springs[i].ij;
1404                                 springs[temp_index].kl = index2;
1405                                 VECSUB(temp, mvert[index2].co, mvert[springs[i].ij].co);
1406                                 springs[temp_index].restlen =  sqrt(INPR(temp, temp));
1407                                 springs[temp_index].type = BENDING;
1408                                 BLI_edgehash_insert(edgehash, springs[temp_index].ij, index2, NULL);
1409                                 bend_springs++;
1410
1411                         }
1412                         search = search->next;   
1413                 }
1414         }
1415
1416         cloth->numsprings = struct_springs + shear_springs + bend_springs;
1417
1418         for(i = 0; i < numverts; i++)
1419         {
1420                 BLI_linklist_free(edgelist[i],NULL); 
1421         }
1422         if(edgelist)
1423                 MEM_freeN(edgelist);    
1424
1425         BLI_edgehash_free(edgehash, NULL);
1426
1427         return 1;
1428
1429 } /* cloth_build_springs */
1430 /***************************************************************************************
1431 * SPRING NETWORK BUILDING IMPLEMENTATION END
1432 ***************************************************************************************/
1433