- split {curve,lattice,armature}_deform_verts out of mesh_deform
[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_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_lattice_types.h"
52 #include "DNA_curve_types.h"
53 #include "DNA_key_types.h"
54
55 #include "BKE_anim.h"
56 #include "BKE_armature.h"
57 #include "BKE_curve.h"
58 #include "BKE_deform.h"
59 #include "BKE_displist.h"
60 #include "BKE_global.h"
61 #include "BKE_key.h"
62 #include "BKE_lattice.h"
63 #include "BKE_library.h"
64 #include "BKE_main.h"
65 #include "BKE_object.h"
66 #include "BKE_screen.h"
67 #include "BKE_utildefines.h"
68
69 #ifdef HAVE_CONFIG_H
70 #include <config.h>
71 #endif
72
73 #include "blendef.h"
74
75 Lattice *editLatt=0, *deformLatt=0;
76
77 float *latticedata=0, latmat[4][4];
78
79 void resizelattice(Lattice *lt)
80 {
81         BPoint *bp;
82         int u, v, w;
83         float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
84         
85
86         MEM_freeN(lt->def);
87         lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
88         
89         bp= lt->def;
90         
91         while(lt->pntsu*lt->pntsv*lt->pntsw > 32000) {
92                 if( lt->pntsu>=lt->pntsv && lt->pntsu>=lt->pntsw) lt->pntsu--;
93                 else if( lt->pntsv>=lt->pntsu && lt->pntsv>=lt->pntsw) lt->pntsv--;
94                 else lt->pntsw--;
95         }
96         
97         calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
98         calc_lat_fudu(lt->flag, lt->pntsv, &fv, &dv);
99         calc_lat_fudu(lt->flag, lt->pntsw, &fw, &dw);
100         
101         vec[2]= fw;
102         for(w=0; w<lt->pntsw; w++) {
103                 vec[1]= fv;
104                 for(v=0; v<lt->pntsv; v++) {
105                         vec[0]= fu;
106                         for(u=0; u<lt->pntsu; u++, bp++) {
107                                 VECCOPY(bp->vec, vec);
108                                 vec[0]+= du;
109                         }
110                         vec[1]+= dv;
111                 }
112                 vec[2]+= dw;
113         }
114 }
115
116 Lattice *add_lattice()
117 {
118         Lattice *lt;
119         
120         lt= alloc_libblock(&G.main->latt, ID_LT, "Lattice");
121         
122         lt->pntsu=lt->pntsv=lt->pntsw= 2;
123         lt->flag= LT_GRID;
124         
125         lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
126         
127         /* temporally */
128         lt->def= MEM_callocN(sizeof(BPoint), "lattvert");
129         
130         resizelattice(lt);      /* creates a uniform lattice */
131                 
132         return lt;
133 }
134
135 Lattice *copy_lattice(Lattice *lt)
136 {
137         Lattice *ltn;
138
139         ltn= copy_libblock(lt);
140         ltn->def= MEM_dupallocN(lt->def);
141                 
142         id_us_plus((ID *)ltn->ipo);
143
144         ltn->key= copy_key(ltn->key);
145         if(ltn->key) ltn->key->from= (ID *)ltn;
146         
147         return ltn;
148 }
149
150 void free_lattice(Lattice *lt)
151 {
152         if(lt->def) MEM_freeN(lt->def);
153 }
154
155
156 void make_local_lattice(Lattice *lt)
157 {
158         Object *ob;
159         Lattice *ltn;
160         int local=0, lib=0;
161
162         /* - only lib users: do nothing
163          * - only local users: set flag
164          * - mixed: make copy
165          */
166         
167         if(lt->id.lib==0) return;
168         if(lt->id.us==1) {
169                 lt->id.lib= 0;
170                 lt->id.flag= LIB_LOCAL;
171                 new_id(0, (ID *)lt, 0);
172                 return;
173         }
174         
175         ob= G.main->object.first;
176         while(ob) {
177                 if(ob->data==lt) {
178                         if(ob->id.lib) lib= 1;
179                         else local= 1;
180                 }
181                 ob= ob->id.next;
182         }
183         
184         if(local && lib==0) {
185                 lt->id.lib= 0;
186                 lt->id.flag= LIB_LOCAL;
187                 new_id(0, (ID *)lt, 0);
188         }
189         else if(local && lib) {
190                 ltn= copy_lattice(lt);
191                 ltn->id.us= 0;
192                 
193                 ob= G.main->object.first;
194                 while(ob) {
195                         if(ob->data==lt) {
196                                 
197                                 if(ob->id.lib==0) {
198                                         ob->data= ltn;
199                                         ltn->id.us++;
200                                         lt->id.us--;
201                                 }
202                         }
203                         ob= ob->id.next;
204                 }
205         }
206 }
207
208
209
210 void calc_lat_fudu(int flag, int res, float *fu, float *du)
211 {
212         
213         if(res==1) {
214                 *fu= 0.0;
215                 *du= 0.0;
216         }
217         else if(flag & LT_GRID) {
218                 *fu= -0.5f*(res-1);
219                 *du= 1.0f;
220         }
221         else {
222                 *fu= -1.0f;
223                 *du= 2.0f/(res-1);
224         }
225         
226 }
227
228 void init_latt_deform(Object *oblatt, Object *ob)
229 {
230         /* we make an array with all differences */
231         BPoint *bp;
232         float *fp, imat[4][4];
233         float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
234         int u, v, w;
235         
236         if(oblatt==G.obedit) deformLatt= editLatt;
237         else deformLatt= oblatt->data;
238         
239         fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
240         
241         lattice_modifier(oblatt, 's');
242         bp= deformLatt->def;
243
244         //if(ob) where_is_object(ob); causes lag here, but why! (ton)
245
246         /* for example with a particle system: ob==0 */
247         if(ob==0) {
248                 /* in deformspace, calc matrix  */
249                 Mat4Invert(latmat, oblatt->obmat);
250         
251                 /* back: put in deform array */
252                 Mat4Invert(imat, latmat);
253         }
254         else {
255                 /* in deformspace, calc matrix */
256                 Mat4Invert(imat, oblatt->obmat);
257                 Mat4MulMat4(latmat, ob->obmat, imat);
258         
259                 /* back: put in deform array */
260                 Mat4Invert(imat, latmat);
261         }
262         calc_lat_fudu(deformLatt->flag, deformLatt->pntsu, &fu, &du);
263         calc_lat_fudu(deformLatt->flag, deformLatt->pntsv, &fv, &dv);
264         calc_lat_fudu(deformLatt->flag, deformLatt->pntsw, &fw, &dw);
265         
266         /* we keep calculating the u v w lattice coordinates, not enough reason to store that */
267         
268         vec[2]= fw;
269         for(w=0; w<deformLatt->pntsw; w++) {
270                 vec[1]= fv;
271                 for(v=0; v<deformLatt->pntsv; v++) {
272                         vec[0]= fu;
273                         for(u=0; u<deformLatt->pntsu; u++, bp++) {
274                                 
275                                 VecSubf(fp, bp->vec, vec);
276                                 Mat4Mul3Vecfl(imat, fp);
277                 
278                                 vec[0]+= du;
279                                 fp+= 3;
280                         }
281                         vec[1]+= dv;
282                 }
283                 vec[2]+= dw;
284         }
285
286         lattice_modifier(oblatt, 'e');
287
288 }
289
290 void calc_latt_deform(float *co)
291 {
292         Lattice *lt;
293         float fu, du, u, v, w, tu[4], tv[4], tw[4];
294         float *fpw, *fpv, *fpu, vec[3];
295         int ui, vi, wi, uu, vv, ww;
296         
297         if(latticedata==0) return;
298         
299         lt= deformLatt; /* just for shorter notation! */
300         
301         /* co is in local coords, treat with latmat */
302         
303         VECCOPY(vec, co);
304         Mat4MulVecfl(latmat, vec);
305         
306         /* u v w coords */
307         
308         if(lt->pntsu>1) {
309                 calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
310                 u= (vec[0]-fu)/du;
311                 ui= (int)floor(u);
312                 u -= ui;
313                 set_four_ipo(u, tu, lt->typeu);
314         }
315         else {
316                 tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
317                 ui= 0;
318         }
319         
320         if(lt->pntsv>1) {
321                 calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du);
322                 v= (vec[1]-fu)/du;
323                 vi= (int)floor(v);
324                 v -= vi;
325                 set_four_ipo(v, tv, lt->typev);
326         }
327         else {
328                 tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
329                 vi= 0;
330         }
331         
332         if(lt->pntsw>1) {
333                 calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du);
334                 w= (vec[2]-fu)/du;
335                 wi= (int)floor(w);
336                 w -= wi;
337                 set_four_ipo(w, tw, lt->typew);
338         }
339         else {
340                 tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
341                 wi= 0;
342         }
343         
344         for(ww= wi-1; ww<=wi+2; ww++) {
345                 w= tw[ww-wi+1];
346                 
347                 if(w!=0.0) {
348                         if(ww>0) {
349                                 if(ww<lt->pntsw) fpw= latticedata + 3*ww*lt->pntsu*lt->pntsv;
350                                 else fpw= latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
351                         }
352                         else fpw= latticedata;
353                         
354                         for(vv= vi-1; vv<=vi+2; vv++) {
355                                 v= w*tv[vv-vi+1];
356                                 
357                                 if(v!=0.0) {
358                                         if(vv>0) {
359                                                 if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
360                                                 else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
361                                         }
362                                         else fpv= fpw;
363                                         
364                                         for(uu= ui-1; uu<=ui+2; uu++) {
365                                                 u= v*tu[uu-ui+1];
366                                                 
367                                                 if(u!=0.0) {
368                                                         if(uu>0) {
369                                                                 if(uu<lt->pntsu) fpu= fpv + 3*uu;
370                                                                 else fpu= fpv + 3*(lt->pntsu-1);
371                                                         }
372                                                         else fpu= fpv;
373                                                         
374                                                         co[0]+= u*fpu[0];
375                                                         co[1]+= u*fpu[1];
376                                                         co[2]+= u*fpu[2];
377                                                 }
378                                         }
379                                 }
380                         }
381                 }
382         }
383 }
384
385 void end_latt_deform()
386 {
387
388         MEM_freeN(latticedata);
389         latticedata= 0;
390 }
391
392         /* calculations is in local space of deformed object
393            so we store in latmat transform from path coord inside object 
394          */
395 typedef struct {
396         float dmin[3], dmax[3], dsize, dloc[3];
397         float curvespace[4][4], objectspace[4][4];
398 } CurveDeform;
399
400 static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd)
401 {
402         Mat4Invert(ob->imat, ob->obmat);
403         Mat4MulMat4(cd->objectspace, par->obmat, ob->imat);
404         Mat4Invert(cd->curvespace, cd->objectspace);
405
406         // offset vector for 'no smear'
407         Mat4Invert(par->imat, par->obmat);
408         VecMat4MulVecfl(cd->dloc, par->imat, ob->obmat[3]);
409
410 }
411
412 /* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
413 static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir)        /* returns OK */
414 {
415         Curve *cu= ob->data;
416         BevList *bl;
417         float ctime1;
418         int cycl=0;
419         
420         /* test for cyclic */
421         bl= cu->bev.first;
422         if(bl && bl->poly> -1) cycl= 1;
423
424         if(cycl==0) {
425                 ctime1= CLAMPIS(ctime, 0.0, 1.0);
426         }
427         else ctime1= ctime;
428         
429         /* vec needs 4 items */
430         if(where_on_path(ob, ctime1, vec, dir)) {
431                 
432                 if(cycl==0) {
433                         Path *path= cu->path;
434                         float dvec[3];
435                         
436                         if(ctime < 0.0) {
437                                 VecSubf(dvec, path->data+4, path->data);
438                                 VecMulf(dvec, ctime*(float)path->len);
439                                 VECADD(vec, vec, dvec);
440                         }
441                         else if(ctime > 1.0) {
442                                 VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8);
443                                 VecMulf(dvec, (ctime-1.0)*(float)path->len);
444                                 VECADD(vec, vec, dvec);
445                         }
446                 }
447                 return 1;
448         }
449         return 0;
450 }
451
452         /* for each point, rotate & translate to curve */
453         /* use path, since it has constant distances */
454         /* co: local coord, result local too */
455 static void calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd)
456 {
457         Curve *cu= par->data;
458         float fac, loc[4], dir[3], *quat, q[4], mat[3][3], cent[3];
459         short upflag, index;
460         
461         if(axis==OB_POSX || axis==OB_NEGX) {
462                 upflag= OB_POSZ;
463                 cent[0]= 0.0;
464                 cent[1]= co[1];
465                 cent[2]= co[2];
466                 index= 0;
467         }
468         else if(axis==OB_POSY || axis==OB_NEGY) {
469                 upflag= OB_POSZ;
470                 cent[0]= co[0];
471                 cent[1]= 0.0;
472                 cent[2]= co[2];
473                 index= 1;
474         }
475         else {
476                 upflag= OB_POSY;
477                 cent[0]= co[0];
478                 cent[1]= co[1];
479                 cent[2]= 0.0;
480                 index= 2;
481         }
482         /* to be sure */
483         if(cu->path==NULL) {
484                 calc_curvepath(par);
485                 if(cu->path==NULL) return;      // happens on append...
486         }
487         /* options */
488         if(cu->flag & CU_STRETCH)
489                 fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
490         else
491                 fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
492         
493         if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
494
495                 quat= vectoquat(dir, axis, upflag);
496                 
497                 /* the tilt */
498                 if(loc[3]!=0.0) {
499                         Normalise(dir);
500                         q[0]= (float)cos(0.5*loc[3]);
501                         fac= (float)sin(0.5*loc[3]);
502                         q[1]= -fac*dir[0];
503                         q[2]= -fac*dir[1];
504                         q[3]= -fac*dir[2];
505                         QuatMul(quat, q, quat);
506                 }               
507                 QuatToMat3(quat, mat);
508         
509                 /* local rotation */
510                 Mat3MulVecfl(mat, cent);
511                 
512                 /* translation */
513                 VECADD(co, cent, loc);
514                 
515         }
516
517 }
518
519 void curve_deform_verts(Object *cuOb, Object *target, float (*vertexCos)[3], int numVerts)
520 {
521         Curve *cu = cuOb->data;
522         int a, flag = cu->flag;
523         CurveDeform cd;
524         
525         cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
526
527         init_curve_deform(cuOb, target, &cd);
528                 
529         INIT_MINMAX(cd.dmin, cd.dmax);
530                 
531         for(a=0; a<numVerts; a++) {
532                 Mat4MulVecfl(cd.curvespace, vertexCos[a]);
533                 DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
534         }
535
536         for(a=0; a<numVerts; a++) {
537                 calc_curve_deform(cuOb, vertexCos[a], target->trackflag, &cd);
538                 Mat4MulVecfl(cd.objectspace, vertexCos[a]);
539         }
540
541         cu->flag = flag;
542 }
543
544 void lattice_deform_verts(Object *laOb, Object *target, float (*vertexCos)[3], int numVerts)
545 {
546         int a;
547
548         init_latt_deform(laOb, target);
549
550         for(a=0; a<numVerts; a++) {
551                 calc_latt_deform(vertexCos[a]);
552         }
553
554         end_latt_deform();
555 }
556
557 void armature_deform_verts(Object *armOb, Object *target, float (*vertexCos)[3], int numVerts) 
558 {
559         int a;
560
561         init_armature_deform(armOb, target);
562
563         for(a=0; a<numVerts; a++) {
564                 calc_armature_deform(armOb, vertexCos[a], a);
565         }
566 }
567
568 int object_deform(Object *ob)
569 {
570         Curve *cu;
571         DispList *dl;
572         float *fp;
573         int a, tot;
574
575         if(ob->parent==NULL) return 0;
576         
577         if(ob->parent->type==OB_LATTICE) {
578                 init_latt_deform(ob->parent, ob);
579                 
580                 if(ob->type==OB_MBALL) {
581                         dl=ob->disp.first;
582                         while(dl) {
583                                 fp = dl->verts;
584                                 for(a=0;a<dl->nr;a++,fp+=3)
585                                         calc_latt_deform(fp);
586                                 dl=dl->next;
587                         }
588                 }
589                 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
590                         cu= ob->data;
591                         /* apply deform on displist */
592                         dl= cu->disp.first;
593                         while(dl) {
594                                 
595                                 fp= dl->verts;
596                                 
597                                 if(dl->type==DL_INDEX3) tot=dl->parts;
598                                 else tot= dl->nr*dl->parts;
599                                 
600                                 for(a=0; a<tot; a++, fp+=3) {
601                                         calc_latt_deform(fp);
602                                 }
603                                 
604                                 dl= dl->next;
605                         }
606                 }
607                 end_latt_deform();
608                 return 1;
609         }
610         
611         return 0;
612
613 }
614
615 BPoint *latt_bp(Lattice *lt, int u, int v, int w)
616 {
617         return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
618 }
619
620 void outside_lattice(Lattice *lt)
621 {
622         BPoint *bp, *bp1, *bp2;
623         int u, v, w;
624         float fac1, du=0.0, dv=0.0, dw=0.0;
625
626         bp= lt->def;
627
628         if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
629         if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
630         if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
631                 
632         for(w=0; w<lt->pntsw; w++) {
633                 
634                 for(v=0; v<lt->pntsv; v++) {
635                 
636                         for(u=0; u<lt->pntsu; u++, bp++) {
637                                 if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
638                                 else {
639                                 
640                                         bp->hide= 1;
641                                         bp->f1 &= ~SELECT;
642                                         
643                                         /* u extrema */
644                                         bp1= latt_bp(lt, 0, v, w);
645                                         bp2= latt_bp(lt, lt->pntsu-1, v, w);
646                                         
647                                         fac1= du*u;
648                                         bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
649                                         bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
650                                         bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
651                                         
652                                         /* v extrema */
653                                         bp1= latt_bp(lt, u, 0, w);
654                                         bp2= latt_bp(lt, u, lt->pntsv-1, w);
655                                         
656                                         fac1= dv*v;
657                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
658                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
659                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
660                                         
661                                         /* w extrema */
662                                         bp1= latt_bp(lt, u, v, 0);
663                                         bp2= latt_bp(lt, u, v, lt->pntsw-1);
664                                         
665                                         fac1= dw*w;
666                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
667                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
668                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
669                                         
670                                         VecMulf(bp->vec, 0.3333333f);
671                                         
672                                 }
673                         }
674                         
675                 }
676                 
677         }
678         
679 }