removed blenderdef.h, BIF_*, BDR_* and BSE_* header files (except for BIF_gl.h and...
[blender.git] / source / blender / blenkernel / intern / lattice.c
1 /**
2  * lattice.c
3  *
4  *
5  * $Id$
6  *
7  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version. The Blender
13  * Foundation also sells licenses for use in proprietary software under
14  * the Blender License.  See http://www.blender.org/BL/ for information
15  * about this.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27  * All rights reserved.
28  *
29  * The Original Code is: all of this file.
30  *
31  * Contributor(s): none yet.
32  *
33  * ***** END GPL/BL DUAL LICENSE BLOCK *****
34  */
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <math.h>
39 #include <stdlib.h>
40
41 #include "MEM_guardedalloc.h"
42
43 #include "BLI_blenlib.h"
44 #include "BLI_arithb.h"
45
46 #include "DNA_armature_types.h"
47 #include "DNA_ipo_types.h"
48 #include "DNA_mesh_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_modifier_types.h"
51 #include "DNA_object_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_lattice_types.h"
54 #include "DNA_curve_types.h"
55 #include "DNA_key_types.h"
56
57 #include "BKE_anim.h"
58 #include "BKE_armature.h"
59 #include "BKE_curve.h"
60 #include "BKE_cdderivedmesh.h"
61 #include "BKE_DerivedMesh.h"
62 #include "BKE_deform.h"
63 #include "BKE_displist.h"
64 #include "BKE_global.h"
65 #include "BKE_ipo.h"
66 #include "BKE_key.h"
67 #include "BKE_lattice.h"
68 #include "BKE_library.h"
69 #include "BKE_main.h"
70 #include "BKE_mesh.h"
71 #include "BKE_modifier.h"
72 #include "BKE_object.h"
73 #include "BKE_screen.h"
74 #include "BKE_utildefines.h"
75
76 //XXX #include "BIF_editdeform.h"
77
78 #ifdef HAVE_CONFIG_H
79 #include <config.h>
80 #endif
81
82 Lattice *editLatt=0;
83 static Lattice *deformLatt=0;
84
85 static float *latticedata=0, latmat[4][4];
86
87 void calc_lat_fudu(int flag, int res, float *fu, float *du)
88 {
89         if(res==1) {
90                 *fu= 0.0;
91                 *du= 0.0;
92         }
93         else if(flag & LT_GRID) {
94                 *fu= -0.5f*(res-1);
95                 *du= 1.0f;
96         }
97         else {
98                 *fu= -1.0f;
99                 *du= 2.0f/(res-1);
100         }
101 }
102
103 void resizelattice(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
104 {
105         BPoint *bp;
106         int i, u, v, w;
107         float fu, fv, fw, uc, vc, wc, du=0.0, dv=0.0, dw=0.0;
108         float *co, (*vertexCos)[3] = NULL;
109         
110         /* vertex weight groups are just freed all for now */
111         if(lt->dvert) {
112                 free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
113                 lt->dvert= NULL;
114         }
115         
116         while(uNew*vNew*wNew > 32000) {
117                 if( uNew>=vNew && uNew>=wNew) uNew--;
118                 else if( vNew>=uNew && vNew>=wNew) vNew--;
119                 else wNew--;
120         }
121
122         vertexCos = MEM_mallocN(sizeof(*vertexCos)*uNew*vNew*wNew, "tmp_vcos");
123
124         calc_lat_fudu(lt->flag, uNew, &fu, &du);
125         calc_lat_fudu(lt->flag, vNew, &fv, &dv);
126         calc_lat_fudu(lt->flag, wNew, &fw, &dw);
127
128                 /* If old size is different then resolution changed in interface,
129                  * try to do clever reinit of points. Pretty simply idea, we just
130                  * deform new verts by old lattice, but scaling them to match old
131                  * size first.
132                  */
133         if (ltOb) {
134                 if (uNew!=1 && lt->pntsu!=1) {
135                         fu = lt->fu;
136                         du = (lt->pntsu-1)*lt->du/(uNew-1);
137                 }
138
139                 if (vNew!=1 && lt->pntsv!=1) {
140                         fv = lt->fv;
141                         dv = (lt->pntsv-1)*lt->dv/(vNew-1);
142                 }
143
144                 if (wNew!=1 && lt->pntsw!=1) {
145                         fw = lt->fw;
146                         dw = (lt->pntsw-1)*lt->dw/(wNew-1);
147                 }
148         }
149
150         co = vertexCos[0];
151         for(w=0,wc=fw; w<wNew; w++,wc+=dw) {
152                 for(v=0,vc=fv; v<vNew; v++,vc+=dv) {
153                         for(u=0,uc=fu; u<uNew; u++,co+=3,uc+=du) {
154                                 co[0] = uc;
155                                 co[1] = vc;
156                                 co[2] = wc;
157                         }
158                 }
159         }
160         
161         if (ltOb) {
162                 float mat[4][4];
163                 int typeu = lt->typeu, typev = lt->typev, typew = lt->typew;
164
165                         /* works best if we force to linear type (endpoints match) */
166                 lt->typeu = lt->typev = lt->typew = KEY_LINEAR;
167
168                         /* prevent using deformed locations */
169                 freedisplist(&ltOb->disp);
170
171                 Mat4CpyMat4(mat, ltOb->obmat);
172                 Mat4One(ltOb->obmat);
173                 lattice_deform_verts(ltOb, NULL, NULL, vertexCos, uNew*vNew*wNew, NULL);
174                 Mat4CpyMat4(ltOb->obmat, mat);
175
176                 lt->typeu = typeu;
177                 lt->typev = typev;
178                 lt->typew = typew;
179         }
180
181         lt->fu = fu;
182         lt->fv = fv;
183         lt->fw = fw;
184         lt->du = du;
185         lt->dv = dv;
186         lt->dw = dw;
187
188         lt->pntsu = uNew;
189         lt->pntsv = vNew;
190         lt->pntsw = wNew;
191
192         MEM_freeN(lt->def);
193         lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
194         
195         bp= lt->def;
196         
197         for (i=0; i<lt->pntsu*lt->pntsv*lt->pntsw; i++,bp++) {
198                 VECCOPY(bp->vec, vertexCos[i]);
199         }
200
201         MEM_freeN(vertexCos);
202 }
203
204 Lattice *add_lattice(char *name)
205 {
206         Lattice *lt;
207         
208         lt= alloc_libblock(&G.main->latt, ID_LT, name);
209         
210         lt->flag= LT_GRID;
211         
212         lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
213         
214         lt->def= MEM_callocN(sizeof(BPoint), "lattvert"); /* temporary */
215         resizelattice(lt, 2, 2, 2, NULL);       /* creates a uniform lattice */
216                 
217         return lt;
218 }
219
220 Lattice *copy_lattice(Lattice *lt)
221 {
222         Lattice *ltn;
223
224         ltn= copy_libblock(lt);
225         ltn->def= MEM_dupallocN(lt->def);
226                 
227         id_us_plus((ID *)ltn->ipo);
228
229         ltn->key= copy_key(ltn->key);
230         if(ltn->key) ltn->key->from= (ID *)ltn;
231         
232         if(lt->dvert) {
233                 int tot= lt->pntsu*lt->pntsv*lt->pntsw;
234                 ltn->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
235                 copy_dverts(ltn->dvert, lt->dvert, tot);
236         }
237         
238         return ltn;
239 }
240
241 void free_lattice(Lattice *lt)
242 {
243         if(lt->def) MEM_freeN(lt->def);
244         if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
245 }
246
247
248 void make_local_lattice(Lattice *lt)
249 {
250         Object *ob;
251         Lattice *ltn;
252         int local=0, lib=0;
253
254         /* - only lib users: do nothing
255          * - only local users: set flag
256          * - mixed: make copy
257          */
258         
259         if(lt->id.lib==0) return;
260         if(lt->id.us==1) {
261                 lt->id.lib= 0;
262                 lt->id.flag= LIB_LOCAL;
263                 new_id(0, (ID *)lt, 0);
264                 return;
265         }
266         
267         ob= G.main->object.first;
268         while(ob) {
269                 if(ob->data==lt) {
270                         if(ob->id.lib) lib= 1;
271                         else local= 1;
272                 }
273                 ob= ob->id.next;
274         }
275         
276         if(local && lib==0) {
277                 lt->id.lib= 0;
278                 lt->id.flag= LIB_LOCAL;
279                 new_id(0, (ID *)lt, 0);
280         }
281         else if(local && lib) {
282                 ltn= copy_lattice(lt);
283                 ltn->id.us= 0;
284                 
285                 ob= G.main->object.first;
286                 while(ob) {
287                         if(ob->data==lt) {
288                                 
289                                 if(ob->id.lib==0) {
290                                         ob->data= ltn;
291                                         ltn->id.us++;
292                                         lt->id.us--;
293                                 }
294                         }
295                         ob= ob->id.next;
296                 }
297         }
298 }
299
300 void init_latt_deform(Object *oblatt, Object *ob)
301 {
302                 /* we make an array with all differences */
303         Lattice *lt = deformLatt = (oblatt==G.obedit)?editLatt:oblatt->data;
304         BPoint *bp = lt->def;
305         DispList *dl = find_displist(&oblatt->disp, DL_VERTS);
306         float *co = dl?dl->verts:NULL;
307         float *fp, imat[4][4];
308         float fu, fv, fw;
309         int u, v, w;
310
311         fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
312         
313                 /* for example with a particle system: ob==0 */
314         if(ob==0) {
315                 /* in deformspace, calc matrix  */
316                 Mat4Invert(latmat, oblatt->obmat);
317         
318                 /* back: put in deform array */
319                 Mat4Invert(imat, latmat);
320         }
321         else {
322                 /* in deformspace, calc matrix */
323                 Mat4Invert(imat, oblatt->obmat);
324                 Mat4MulMat4(latmat, ob->obmat, imat);
325         
326                 /* back: put in deform array */
327                 Mat4Invert(imat, latmat);
328         }
329         
330         for(w=0,fw=lt->fw; w<lt->pntsw; w++,fw+=lt->dw) {
331                 for(v=0,fv=lt->fv; v<lt->pntsv; v++, fv+=lt->dv) {
332                         for(u=0,fu=lt->fu; u<lt->pntsu; u++, bp++, co+=3, fp+=3, fu+=lt->du) {
333                                 if (dl) {
334                                         fp[0] = co[0] - fu;
335                                         fp[1] = co[1] - fv;
336                                         fp[2] = co[2] - fw;
337                                 } else {
338                                         fp[0] = bp->vec[0] - fu;
339                                         fp[1] = bp->vec[1] - fv;
340                                         fp[2] = bp->vec[2] - fw;
341                                 }
342
343                                 Mat4Mul3Vecfl(imat, fp);
344                         }
345                 }
346         }
347 }
348
349 void calc_latt_deform(float *co, float weight)
350 {
351         Lattice *lt;
352         float u, v, w, tu[4], tv[4], tw[4];
353         float *fpw, *fpv, *fpu, vec[3];
354         int ui, vi, wi, uu, vv, ww;
355         
356         if(latticedata==0) return;
357         
358         lt= deformLatt; /* just for shorter notation! */
359         
360         /* co is in local coords, treat with latmat */
361         
362         VECCOPY(vec, co);
363         Mat4MulVecfl(latmat, vec);
364         
365         /* u v w coords */
366         
367         if(lt->pntsu>1) {
368                 u= (vec[0]-lt->fu)/lt->du;
369                 ui= (int)floor(u);
370                 u -= ui;
371                 set_four_ipo(u, tu, lt->typeu);
372         }
373         else {
374                 tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
375                 ui= 0;
376         }
377         
378         if(lt->pntsv>1) {
379                 v= (vec[1]-lt->fv)/lt->dv;
380                 vi= (int)floor(v);
381                 v -= vi;
382                 set_four_ipo(v, tv, lt->typev);
383         }
384         else {
385                 tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
386                 vi= 0;
387         }
388         
389         if(lt->pntsw>1) {
390                 w= (vec[2]-lt->fw)/lt->dw;
391                 wi= (int)floor(w);
392                 w -= wi;
393                 set_four_ipo(w, tw, lt->typew);
394         }
395         else {
396                 tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
397                 wi= 0;
398         }
399         
400         for(ww= wi-1; ww<=wi+2; ww++) {
401                 w= tw[ww-wi+1];
402                 
403                 if(w!=0.0) {
404                         if(ww>0) {
405                                 if(ww<lt->pntsw) fpw= latticedata + 3*ww*lt->pntsu*lt->pntsv;
406                                 else fpw= latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
407                         }
408                         else fpw= latticedata;
409                         
410                         for(vv= vi-1; vv<=vi+2; vv++) {
411                                 v= w*tv[vv-vi+1];
412                                 
413                                 if(v!=0.0) {
414                                         if(vv>0) {
415                                                 if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
416                                                 else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
417                                         }
418                                         else fpv= fpw;
419                                         
420                                         for(uu= ui-1; uu<=ui+2; uu++) {
421                                                 u= weight*v*tu[uu-ui+1];
422                                                 
423                                                 if(u!=0.0) {
424                                                         if(uu>0) {
425                                                                 if(uu<lt->pntsu) fpu= fpv + 3*uu;
426                                                                 else fpu= fpv + 3*(lt->pntsu-1);
427                                                         }
428                                                         else fpu= fpv;
429                                                         
430                                                         co[0]+= u*fpu[0];
431                                                         co[1]+= u*fpu[1];
432                                                         co[2]+= u*fpu[2];
433                                                 }
434                                         }
435                                 }
436                         }
437                 }
438         }
439 }
440
441 void end_latt_deform()
442 {
443
444         MEM_freeN(latticedata);
445         latticedata= 0;
446 }
447
448         /* calculations is in local space of deformed object
449            so we store in latmat transform from path coord inside object 
450          */
451 typedef struct {
452         float dmin[3], dmax[3], dsize, dloc[3];
453         float curvespace[4][4], objectspace[4][4], objectspace3[3][3];
454         int no_rot_axis;
455 } CurveDeform;
456
457 static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc)
458 {
459         Mat4Invert(ob->imat, ob->obmat);
460         Mat4MulMat4(cd->objectspace, par->obmat, ob->imat);
461         Mat4Invert(cd->curvespace, cd->objectspace);
462         Mat3CpyMat4(cd->objectspace3, cd->objectspace);
463         
464         // offset vector for 'no smear'
465         if(dloc) {
466                 Mat4Invert(par->imat, par->obmat);
467                 VecMat4MulVecfl(cd->dloc, par->imat, ob->obmat[3]);
468         }
469         else cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f;
470         
471         cd->no_rot_axis= 0;
472 }
473
474 /* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
475 static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)        /* returns OK */
476 {
477         Curve *cu= ob->data;
478         BevList *bl;
479         float ctime1;
480         int cycl=0;
481         
482         /* test for cyclic */
483         bl= cu->bev.first;
484         if (!bl->nr) return 0;
485         if(bl && bl->poly> -1) cycl= 1;
486
487         if(cycl==0) {
488                 ctime1= CLAMPIS(ctime, 0.0, 1.0);
489         }
490         else ctime1= ctime;
491         
492         /* vec needs 4 items */
493         if(where_on_path(ob, ctime1, vec, dir)) {
494                 
495                 if(cycl==0) {
496                         Path *path= cu->path;
497                         float dvec[3];
498                         
499                         if(ctime < 0.0) {
500                                 VecSubf(dvec, path->data+4, path->data);
501                                 VecMulf(dvec, ctime*(float)path->len);
502                                 VECADD(vec, vec, dvec);
503                         }
504                         else if(ctime > 1.0) {
505                                 VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8);
506                                 VecMulf(dvec, (ctime-1.0)*(float)path->len);
507                                 VECADD(vec, vec, dvec);
508                         }
509                 }
510                 return 1;
511         }
512         return 0;
513 }
514
515         /* for each point, rotate & translate to curve */
516         /* use path, since it has constant distances */
517         /* co: local coord, result local too */
518         /* returns quaternion for rotation, using cd->no_rot_axis */
519         /* axis is using another define!!! */
520 static float *calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd)
521 {
522         Curve *cu= par->data;
523         float fac, loc[4], dir[3], cent[3];
524         short upflag, index;
525         
526         if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) {
527                 upflag= OB_POSZ;
528                 cent[0]= 0.0;
529                 cent[1]= co[1];
530                 cent[2]= co[2];
531                 index= 0;
532         }
533         else if(axis==MOD_CURVE_POSY || axis==MOD_CURVE_NEGY) {
534                 upflag= OB_POSZ;
535                 cent[0]= co[0];
536                 cent[1]= 0.0;
537                 cent[2]= co[2];
538                 index= 1;
539         }
540         else {
541                 upflag= OB_POSY;
542                 cent[0]= co[0];
543                 cent[1]= co[1];
544                 cent[2]= 0.0;
545                 index= 2;
546         }
547         /* to be sure, mostly after file load */
548         if(cu->path==NULL) {
549                 makeDispListCurveTypes(par, 0);
550                 if(cu->path==NULL) return NULL; // happens on append...
551         }
552         
553         /* options */
554         if(ELEM3(axis, OB_NEGX, OB_NEGY, OB_NEGZ)) {
555                 if(cu->flag & CU_STRETCH)
556                         fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
557                 else
558                         fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist);
559         }
560         else {
561                 if(cu->flag & CU_STRETCH)
562                         fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
563                 else
564                         fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
565         }
566         
567         /* we want the ipo to work on the default 100 frame range, because there's no  
568            actual time involved in path position */
569         if(cu->ipo) {
570                 fac*= 100.0f;
571                 if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0)
572                         fac/= 100.0;
573         }
574         
575         if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
576                 float q[4], mat[3][3];
577                 float *quat;
578                 
579                 if(cd->no_rot_axis)     /* set by caller */
580                         dir[cd->no_rot_axis-1]= 0.0f;
581                 
582                 /* -1 for compatibility with old track defines */
583                 quat= vectoquat(dir, axis-1, upflag);   /* gives static quat */
584                 
585                 /* the tilt */
586                 if(loc[3]!=0.0) {
587                         Normalize(dir);
588                         q[0]= (float)cos(0.5*loc[3]);
589                         fac= (float)sin(0.5*loc[3]);
590                         q[1]= -fac*dir[0];
591                         q[2]= -fac*dir[1];
592                         q[3]= -fac*dir[2];
593                         QuatMul(quat, q, quat);
594                 }               
595                 QuatToMat3(quat, mat);
596         
597                 /* local rotation */
598                 Mat3MulVecfl(mat, cent);
599                 
600                 /* translation */
601                 VECADD(co, cent, loc);
602                 
603                 return quat;
604         }
605         return NULL;
606 }
607
608 void curve_deform_verts(Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, char *vgroup, short defaxis)
609 {
610         Curve *cu = cuOb->data;
611         int a, flag = cu->flag;
612         CurveDeform cd;
613         int use_vgroups;
614         
615         cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
616
617         init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0);
618                 
619         /* check whether to use vertex groups (only possible if target is a Mesh)
620          * we want either a Mesh with no derived data, or derived data with
621          * deformverts
622          */
623         if(target && target->type==OB_MESH) {
624                 /* if there's derived data without deformverts, don't use vgroups */
625                 if(dm && !dm->getVertData(dm, 0, CD_MDEFORMVERT))
626                         use_vgroups = 0;
627                 else
628                         use_vgroups = 1;
629         } else
630                 use_vgroups = 0;
631         
632         if(vgroup && vgroup[0] && use_vgroups) {
633                 bDeformGroup *curdef;
634                 Mesh *me= target->data;
635                 int index;
636                 
637                 /* find the group (weak loop-in-loop) */
638                 for(index = 0, curdef = target->defbase.first; curdef;
639                     curdef = curdef->next, index++)
640                         if (!strcmp(curdef->name, vgroup))
641                                 break;
642
643                 if(curdef && (me->dvert || dm)) {
644                         MDeformVert *dvert = me->dvert;
645                         float vec[3];
646                         int j;
647
648                         INIT_MINMAX(cd.dmin, cd.dmax);
649
650                         for(a = 0; a < numVerts; a++, dvert++) {
651                                 if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
652
653                                 for(j = 0; j < dvert->totweight; j++) {
654                                         if(dvert->dw[j].def_nr == index) {
655                                                 Mat4MulVecfl(cd.curvespace, vertexCos[a]);
656                                                 DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
657                                                 break;
658                                         }
659                                 }
660                         }
661
662                         dvert = me->dvert;
663                         for(a = 0; a < numVerts; a++, dvert++) {
664                                 if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
665
666                                 for(j = 0; j < dvert->totweight; j++) {
667                                         if(dvert->dw[j].def_nr == index) {
668                                                 VECCOPY(vec, vertexCos[a]);
669                                                 calc_curve_deform(cuOb, vec, defaxis, &cd);
670                                                 VecLerpf(vertexCos[a], vertexCos[a], vec,
671                                                          dvert->dw[j].weight);
672                                                 Mat4MulVecfl(cd.objectspace, vertexCos[a]);
673                                                 break;
674                                         }
675                                 }
676                         }
677                 }
678         } else {
679                 INIT_MINMAX(cd.dmin, cd.dmax);
680                         
681                 for(a = 0; a < numVerts; a++) {
682                         Mat4MulVecfl(cd.curvespace, vertexCos[a]);
683                         DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
684                 }
685
686                 for(a = 0; a < numVerts; a++) {
687                         calc_curve_deform(cuOb, vertexCos[a], defaxis, &cd);
688                         Mat4MulVecfl(cd.objectspace, vertexCos[a]);
689                 }
690         }
691         cu->flag = flag;
692 }
693
694 /* input vec and orco = local coord in armature space */
695 /* orco is original not-animated or deformed reference point */
696 /* result written in vec and mat */
697 void curve_deform_vector(Object *cuOb, Object *target, float *orco, float *vec, float mat[][3], int no_rot_axis)
698 {
699         CurveDeform cd;
700         float *quat;
701         
702         init_curve_deform(cuOb, target, &cd, 0);        /* 0 no dloc */
703         cd.no_rot_axis= no_rot_axis;                            /* option to only rotate for XY, for example */
704         
705         VECCOPY(cd.dmin, orco);
706         VECCOPY(cd.dmax, orco);
707
708         Mat4MulVecfl(cd.curvespace, vec);
709         
710         quat= calc_curve_deform(cuOb, vec, target->trackflag+1, &cd);
711         if(quat) {
712                 float qmat[3][3];
713                 
714                 QuatToMat3(quat, qmat);
715                 Mat3MulMat3(mat, qmat, cd.objectspace3);
716         }
717         else
718                 Mat3One(mat);
719         
720         Mat4MulVecfl(cd.objectspace, vec);
721
722 }
723
724 void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
725                           float (*vertexCos)[3], int numVerts, char *vgroup)
726 {
727         int a;
728         int use_vgroups;
729
730         init_latt_deform(laOb, target);
731
732         /* check whether to use vertex groups (only possible if target is a Mesh)
733          * we want either a Mesh with no derived data, or derived data with
734          * deformverts
735          */
736         if(target && target->type==OB_MESH) {
737                 /* if there's derived data without deformverts, don't use vgroups */
738                 if(dm && !dm->getVertData(dm, 0, CD_MDEFORMVERT))
739                         use_vgroups = 0;
740                 else
741                         use_vgroups = 1;
742         } else
743                 use_vgroups = 0;
744         
745         if(vgroup && vgroup[0] && use_vgroups) {
746                 bDeformGroup *curdef;
747                 Mesh *me = target->data;
748                 int index = 0;
749                 
750                 /* find the group (weak loop-in-loop) */
751                 for(curdef = target->defbase.first; curdef;
752                     curdef = curdef->next, index++)
753                         if(!strcmp(curdef->name, vgroup)) break;
754
755                 if(curdef && (me->dvert || dm)) {
756                         MDeformVert *dvert = me->dvert;
757                         int j;
758                         
759                         for(a = 0; a < numVerts; a++, dvert++) {
760                                 if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
761                                 for(j = 0; j < dvert->totweight; j++) {
762                                         if (dvert->dw[j].def_nr == index) {
763                                                 calc_latt_deform(vertexCos[a], dvert->dw[j].weight);
764                                         }
765                                 }
766                         }
767                 }
768         } else {
769                 for(a = 0; a < numVerts; a++) {
770                         calc_latt_deform(vertexCos[a], 1.0f);
771                 }
772         }
773         end_latt_deform();
774 }
775
776 int object_deform_mball(Object *ob)
777 {
778         if(ob->parent && ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
779                 DispList *dl;
780
781                 for (dl=ob->disp.first; dl; dl=dl->next) {
782                         lattice_deform_verts(ob->parent, ob, NULL,
783                                              (float(*)[3]) dl->verts, dl->nr, NULL);
784                 }
785
786                 return 1;
787         } else {
788                 return 0;
789         }
790 }
791
792 static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
793 {
794         return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
795 }
796
797 void outside_lattice(Lattice *lt)
798 {
799         BPoint *bp, *bp1, *bp2;
800         int u, v, w;
801         float fac1, du=0.0, dv=0.0, dw=0.0;
802
803         bp= lt->def;
804
805         if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
806         if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
807         if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
808                 
809         for(w=0; w<lt->pntsw; w++) {
810                 
811                 for(v=0; v<lt->pntsv; v++) {
812                 
813                         for(u=0; u<lt->pntsu; u++, bp++) {
814                                 if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
815                                 else {
816                                 
817                                         bp->hide= 1;
818                                         bp->f1 &= ~SELECT;
819                                         
820                                         /* u extrema */
821                                         bp1= latt_bp(lt, 0, v, w);
822                                         bp2= latt_bp(lt, lt->pntsu-1, v, w);
823                                         
824                                         fac1= du*u;
825                                         bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
826                                         bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
827                                         bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
828                                         
829                                         /* v extrema */
830                                         bp1= latt_bp(lt, u, 0, w);
831                                         bp2= latt_bp(lt, u, lt->pntsv-1, w);
832                                         
833                                         fac1= dv*v;
834                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
835                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
836                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
837                                         
838                                         /* w extrema */
839                                         bp1= latt_bp(lt, u, v, 0);
840                                         bp2= latt_bp(lt, u, v, lt->pntsw-1);
841                                         
842                                         fac1= dw*w;
843                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
844                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
845                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
846                                         
847                                         VecMulf(bp->vec, 0.3333333f);
848                                         
849                                 }
850                         }
851                         
852                 }
853                 
854         }
855         
856 }
857
858 float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]
859 {
860         Lattice *lt = (G.obedit==ob)?editLatt:ob->data;
861         int i, numVerts = *numVerts_r = lt->pntsu*lt->pntsv*lt->pntsw;
862         float (*vertexCos)[3] = MEM_mallocN(sizeof(*vertexCos)*numVerts,"lt_vcos");
863
864         for (i=0; i<numVerts; i++) {
865                 VECCOPY(vertexCos[i], lt->def[i].vec);
866         }
867
868         return vertexCos;
869 }
870
871 void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3])
872 {
873         Lattice *lt = ob->data;
874         int i, numVerts = lt->pntsu*lt->pntsv*lt->pntsw;
875
876         for (i=0; i<numVerts; i++) {
877                 VECCOPY(lt->def[i].vec, vertexCos[i]);
878         }
879 }
880
881 void lattice_calc_modifiers(Object *ob)
882 {
883         float (*vertexCos)[3] = NULL;
884         ModifierData *md = modifiers_getVirtualModifierList(ob);
885         int numVerts, editmode = G.obedit==ob;
886
887         freedisplist(&ob->disp);
888
889         if (!editmode) {
890                 do_ob_key(ob);
891         }
892
893         for (; md; md=md->next) {
894                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
895
896                 if (!(md->mode&eModifierMode_Realtime)) continue;
897                 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
898                 if (mti->isDisabled && mti->isDisabled(md)) continue;
899                 if (mti->type!=eModifierTypeType_OnlyDeform) continue;
900
901                 if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
902                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
903         }
904
905         if (vertexCos) {
906                 DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
907                 dl->type = DL_VERTS;
908                 dl->parts = 1;
909                 dl->nr = numVerts;
910                 dl->verts = (float*) vertexCos;
911                 
912                 BLI_addtail(&ob->disp, dl);
913         }
914 }