updated .c files to include:
[blender.git] / source / blender / blenkernel / intern / lattice.c
1 /**
2  * lattice.c      MIXED MODEL
3  * june 2001 ton
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include <stdio.h>
36 #include <string.h>
37 #include <math.h>
38 #include <stdlib.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_arithb.h"
44
45 #include "DNA_armature_types.h"
46 #include "DNA_mesh_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_lattice_types.h"
50 #include "DNA_curve_types.h"
51 #include "DNA_key_types.h"
52 #include "DNA_ika_types.h"
53
54 #include "BKE_utildefines.h"
55 #include "BKE_armature.h"
56 #include "BKE_library.h"
57 #include "BKE_global.h"
58 #include "BKE_main.h"
59 #include "BKE_screen.h"
60 #include "BKE_displist.h"
61 #include "BKE_lattice.h"
62 #include "BKE_key.h"
63 #include "BKE_object.h"
64 #include "BKE_ika.h"
65
66 #ifdef HAVE_CONFIG_H
67 #include <config.h>
68 #endif
69
70 Lattice *editLatt=0, *deformLatt=0;
71
72 float *latticedata=0, latmat[4][4];
73 int lt_applyflag= 0;
74
75 void resizelattice(Lattice *lt)
76 {
77         BPoint *bp;
78         int u, v, w;
79         float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
80         
81
82         MEM_freeN(lt->def);
83         lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
84         
85         bp= lt->def;
86         
87         while(lt->pntsu*lt->pntsv*lt->pntsw > 32000) {
88                 if( lt->pntsu>=lt->pntsv && lt->pntsu>=lt->pntsw) lt->pntsu--;
89                 else if( lt->pntsv>=lt->pntsu && lt->pntsv>=lt->pntsw) lt->pntsv--;
90                 else lt->pntsw--;
91         }
92         
93         calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
94         calc_lat_fudu(lt->flag, lt->pntsv, &fv, &dv);
95         calc_lat_fudu(lt->flag, lt->pntsw, &fw, &dw);
96         
97         vec[2]= fw;
98         for(w=0; w<lt->pntsw; w++) {
99                 vec[1]= fv;
100                 for(v=0; v<lt->pntsv; v++) {
101                         vec[0]= fu;
102                         for(u=0; u<lt->pntsu; u++, bp++) {
103                                 VECCOPY(bp->vec, vec);
104                                 vec[0]+= du;
105                         }
106                         vec[1]+= dv;
107                 }
108                 vec[2]+= dw;
109         }
110 }
111
112 Lattice *add_lattice()
113 {
114         Lattice *lt;
115         
116         lt= alloc_libblock(&G.main->latt, ID_LT, "Lattice");
117         
118         lt->pntsu=lt->pntsv=lt->pntsw= 2;
119         lt->flag= LT_GRID;
120         
121         lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
122         
123         /* tijdelijk */
124         lt->def= MEM_callocN(sizeof(BPoint), "lattvert");
125         
126         resizelattice(lt);      /* maakt een regelmatige lattice */
127                 
128         return lt;
129 }
130
131 Lattice *copy_lattice(Lattice *lt)
132 {
133         Lattice *ltn;
134
135         ltn= copy_libblock(lt);
136         ltn->def= MEM_dupallocN(lt->def);
137                 
138         id_us_plus((ID *)ltn->ipo);
139
140         ltn->key= copy_key(ltn->key);
141         if(ltn->key) ltn->key->from= (ID *)ltn;
142         
143         return ltn;
144 }
145
146 void free_lattice(Lattice *lt)
147 {
148         if(lt->def) MEM_freeN(lt->def);
149 }
150
151
152 void make_local_lattice(Lattice *lt)
153 {
154         Object *ob;
155         Lattice *ltn;
156         int local=0, lib=0;
157         
158         /* - zijn er alleen lib users: niet doen
159          * - zijn er alleen locale users: flag zetten
160          * - mixed: copy
161          */
162         
163         if(lt->id.lib==0) return;
164         if(lt->id.us==1) {
165                 lt->id.lib= 0;
166                 lt->id.flag= LIB_LOCAL;
167                 new_id(0, (ID *)lt, 0);
168                 return;
169         }
170         
171         ob= G.main->object.first;
172         while(ob) {
173                 if(ob->data==lt) {
174                         if(ob->id.lib) lib= 1;
175                         else local= 1;
176                 }
177                 ob= ob->id.next;
178         }
179         
180         if(local && lib==0) {
181                 lt->id.lib= 0;
182                 lt->id.flag= LIB_LOCAL;
183                 new_id(0, (ID *)lt, 0);
184         }
185         else if(local && lib) {
186                 ltn= copy_lattice(lt);
187                 ltn->id.us= 0;
188                 
189                 ob= G.main->object.first;
190                 while(ob) {
191                         if(ob->data==lt) {
192                                 
193                                 if(ob->id.lib==0) {
194                                         ob->data= ltn;
195                                         ltn->id.us++;
196                                         lt->id.us--;
197                                 }
198                         }
199                         ob= ob->id.next;
200                 }
201         }
202 }
203
204
205
206 void calc_lat_fudu(int flag, int res, float *fu, float *du)
207 {
208         
209         if(res==1) {
210                 *fu= 0.0;
211                 *du= 0.0;
212         }
213         else if(flag & LT_GRID) {
214                 *fu= -0.5f*(res-1);
215                 *du= 1.0f;
216         }
217         else {
218                 *fu= -1.0f;
219                 *du= 2.0f/(res-1);
220         }
221         
222 }
223
224 void init_latt_deform(Object *oblatt, Object *ob)
225 {
226         /* we maken een array met alle verschillen */
227         BPoint *bp;
228         float *fp, imat[4][4];
229         float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
230         int u, v, w;
231         
232         if(oblatt==G.obedit) deformLatt= editLatt;
233         else deformLatt= oblatt->data;
234         
235         fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
236         
237         bp= deformLatt->def;
238
239         if(ob) where_is_object(ob);
240
241         /* bijv bij particle systeem: ob==0 */
242         if(ob==0) {
243                 /* in deformspace, matrix berekenen */
244                 Mat4Invert(latmat, oblatt->obmat);
245         
246                 /* terug: in deform array verwerken */
247                 Mat4Invert(imat, latmat);
248         }
249         else {
250                 /* in deformspace, matrix berekenen */
251                 Mat4Invert(imat, oblatt->obmat);
252                 Mat4MulMat4(latmat, ob->obmat, imat);
253         
254                 /* terug: in deform array verwerken */
255                 Mat4Invert(imat, latmat);
256         }
257         calc_lat_fudu(deformLatt->flag, deformLatt->pntsu, &fu, &du);
258         calc_lat_fudu(deformLatt->flag, deformLatt->pntsv, &fv, &dv);
259         calc_lat_fudu(deformLatt->flag, deformLatt->pntsw, &fw, &dw);
260         
261         /* we berekenen hier steeds de u v w lattice coordinaten, weinig reden ze te onthouden */
262         
263         vec[2]= fw;
264         for(w=0; w<deformLatt->pntsw; w++) {
265                 vec[1]= fv;
266                 for(v=0; v<deformLatt->pntsv; v++) {
267                         vec[0]= fu;
268                         for(u=0; u<deformLatt->pntsu; u++, bp++) {
269                                 
270                                 VecSubf(fp, bp->vec, vec);
271                                 Mat4Mul3Vecfl(imat, fp);
272                 
273                                 vec[0]+= du;
274                                 fp+= 3;
275                         }
276                         vec[1]+= dv;
277                 }
278                 vec[2]+= dw;
279         }
280 }
281
282 void calc_latt_deform(float *co)
283 {
284         Lattice *lt;
285         float fu, du, u, v, w, tu[4], tv[4], tw[4];
286         float *fpw, *fpv, *fpu, vec[3];
287         int ui, vi, wi, uu, vv, ww, end, end2;
288         
289         if(latticedata==0) return;
290         
291         lt= deformLatt; /* kortere notatie! */
292         
293         /* co is in lokale coords, met latmat behandelen */
294         
295         VECCOPY(vec, co);
296         Mat4MulVecfl(latmat, vec);
297         
298         /* u v w coords */
299         
300         if(lt->pntsu>1) {
301                 calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
302                 u= (vec[0]-fu)/du;
303                 ui= (int)floor(u);
304                 u -= ui;
305                 set_four_ipo(u, tu, lt->typeu);
306         }
307         else {
308                 tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
309                 ui= 0;
310         }
311         
312         if(lt->pntsv>1) {
313                 calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du);
314                 v= (vec[1]-fu)/du;
315                 vi= (int)floor(v);
316                 v -= vi;
317                 set_four_ipo(v, tv, lt->typev);
318         }
319         else {
320                 tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
321                 vi= 0;
322         }
323         
324         if(lt->pntsw>1) {
325                 calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du);
326                 w= (vec[2]-fu)/du;
327                 wi= (int)floor(w);
328                 w -= wi;
329                 set_four_ipo(w, tw, lt->typew);
330         }
331         else {
332                 tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
333                 wi= 0;
334         }
335         
336         end = wi+2;
337         for(ww= wi-1; ww<=end; ww++) {
338                 w= tw[ww-wi+1];
339                 
340                 if(w!=0.0) {
341                         if(ww>0) {
342                                 if(ww<lt->pntsw) fpw= latticedata + 3*ww*lt->pntsu*lt->pntsv;
343                                 else fpw= latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
344                         }
345                         else fpw= latticedata;
346                         
347                         end2 = vi+2;
348                         for(vv= vi-1; vv<=end; vv++) {
349                                 v= w*tv[vv-vi+1];
350                                 
351                                 if(v!=0.0) {
352                                         if(vv>0) {
353                                                 if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
354                                                 else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
355                                         }
356                                         else fpv= fpw;
357                                         
358                                         for(uu= ui-1; uu<=ui+2; uu++) {
359                                                 u= v*tu[uu-ui+1];
360                                                 
361                                                 if(u!=0.0) {
362                                                         if(uu>0) {
363                                                                 if(uu<lt->pntsu) fpu= fpv + 3*uu;
364                                                                 else fpu= fpv + 3*(lt->pntsu-1);
365                                                         }
366                                                         else fpu= fpv;
367                                                         
368                                                         co[0]+= u*fpu[0];
369                                                         co[1]+= u*fpu[1];
370                                                         co[2]+= u*fpu[2];
371                                                 }
372                                         }
373                                 }
374                         }
375                 }
376         }
377 }
378
379
380 void end_latt_deform()
381 {
382
383         MEM_freeN(latticedata);
384         latticedata= 0;
385 }
386
387
388 int object_deform(Object *ob)
389 {
390         Mesh *me;
391         Curve *cu;
392         DispList *dl;
393         MVert *mvert;
394         float *fp;
395         int a, tot;
396
397         if(ob->parent==0) return 0;
398         
399         /* altijd proberen in deze fie de hele deform te doen: apply! */
400         
401         if(ob->parent->type==OB_LATTICE) {
402                 
403                 init_latt_deform(ob->parent, ob);
404                 
405                 if(ob->type==OB_MESH) {
406                         me= ob->data;
407                         
408                         dl= find_displist_create(&ob->disp, DL_VERTS);
409                         
410                         mvert= me->mvert;
411                         if(dl->verts) MEM_freeN(dl->verts);
412                         dl->nr= me->totvert;
413                         dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
414
415                         for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
416                                 if(lt_applyflag) calc_latt_deform(mvert->co);
417                                 else {
418                                         VECCOPY(fp, mvert->co);
419                                         calc_latt_deform(fp);
420                                 }
421                         }
422                 }
423                 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
424                 
425                         cu= ob->data;
426                         if(lt_applyflag) {
427                                 Nurb *nu;
428                                 BPoint *bp;
429                                 
430                                 nu= cu->nurb.first;
431                                 while(nu) {
432                                         if(nu->bp) {
433                                                 a= nu->pntsu*nu->pntsv;
434                                                 bp= nu->bp;
435                                                 while(a--) {
436                                                         calc_latt_deform(bp->vec);
437                                                         bp++;
438                                                 }
439                                         }
440                                         nu= nu->next;
441                                 }
442                         }
443                         
444                         /* when apply, do this too, looks more interactive */
445                         dl= cu->disp.first;
446                         while(dl) {
447                                 
448                                 fp= dl->verts;
449                                 
450                                 if(dl->type==DL_INDEX3) tot=dl->parts;
451                                 else tot= dl->nr*dl->parts;
452                                 
453                                 for(a=0; a<tot; a++, fp+=3) {
454                                         calc_latt_deform(fp);
455                                 }
456                                 
457                                 dl= dl->next;
458                         }
459                 }
460                 end_latt_deform();
461
462                 boundbox_displist(ob);  
463
464                 return 1;
465         }
466         else if(ob->parent->type==OB_ARMATURE) {
467                 if (ob->partype != PARSKEL){
468                         return 0;
469                 }
470                 
471                 init_armature_deform (ob->parent, ob);
472
473                 switch (ob->type){
474                 case OB_MESH:
475                         me= ob->data;
476                         
477                         dl= find_displist_create(&ob->disp, DL_VERTS);
478                         
479                         mvert= me->mvert;
480                         if(dl->verts) MEM_freeN(dl->verts);
481                         dl->nr= me->totvert;
482                         dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
483
484                         for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
485                                 if(lt_applyflag){
486                                         calc_armature_deform(ob->parent, mvert->co, a);
487                                 }
488                                 else {
489                                         VECCOPY(fp, mvert->co);
490                                         calc_armature_deform(ob->parent, fp, a);
491                                 }
492                         }
493
494                         break;
495                 default:
496                         break;
497                 }
498                 
499                 boundbox_displist(ob);  
500                 return 1;
501         }
502         else if(ob->parent->type==OB_IKA) {
503
504                 Ika *ika;
505                 
506                 if(ob->partype!=PARSKEL) return 0;
507                 
508                 ika= ob->parent->data;
509                 if(ika->def==0) return 0;
510                 
511                 init_skel_deform(ob->parent, ob);
512                 
513                 if(ob->type==OB_MESH) {
514                         me= ob->data;
515                         
516                         dl= find_displist_create(&ob->disp, DL_VERTS);
517                         
518                         mvert= me->mvert;
519                         if(dl->verts) MEM_freeN(dl->verts);
520                         dl->nr= me->totvert;
521                         dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
522
523                         for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
524                                 if(lt_applyflag) calc_skel_deform(ika, mvert->co);
525                                 else {
526                                         VECCOPY(fp, mvert->co);
527                                         calc_skel_deform(ika, fp);
528                                 }
529                         }
530                 }
531                 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
532                 
533                         cu= ob->data;
534                         if(lt_applyflag) {
535                                 Nurb *nu;
536                                 BPoint *bp;
537                                 
538                                 nu= cu->nurb.first;
539                                 while(nu) {
540                                         if(nu->bp) {
541                                                 a= nu->pntsu*nu->pntsv;
542                                                 bp= nu->bp;
543                                                 while(a--) {
544                                                         calc_skel_deform(ika, bp->vec);
545                                                         bp++;
546                                                 }
547                                         }
548                                         nu= nu->next;
549                                 }
550                         }
551                         
552                         /* when apply, do this too, looks more interactive */
553                         dl= cu->disp.first;
554                         while(dl) {
555                                 
556                                 fp= dl->verts;
557                                 tot= dl->nr*dl->parts;
558                                 for(a=0; a<tot; a++, fp+=3) {
559                                         calc_skel_deform(ika, fp);
560                                 }
561                                 
562                                 dl= dl->next;
563                         }
564                 }
565                 
566                 boundbox_displist(ob);
567                 
568                 return 1;
569         }
570         
571         return 0;
572
573 }
574
575 BPoint *latt_bp(Lattice *lt, int u, int v, int w)
576 {
577         return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
578 }
579
580 void outside_lattice(Lattice *lt)
581 {
582         BPoint *bp, *bp1, *bp2;
583         int u, v, w;
584         float fac1, du=0.0, dv=0.0, dw=0.0;
585
586         bp= lt->def;
587
588         if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
589         if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
590         if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
591                 
592         for(w=0; w<lt->pntsw; w++) {
593                 
594                 for(v=0; v<lt->pntsv; v++) {
595                 
596                         for(u=0; u<lt->pntsu; u++, bp++) {
597                                 if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
598                                 else {
599                                 
600                                         bp->hide= 1;
601                                         bp->f1 &= ~SELECT;
602                                         
603                                         /* u extrema */
604                                         bp1= latt_bp(lt, 0, v, w);
605                                         bp2= latt_bp(lt, lt->pntsu-1, v, w);
606                                         
607                                         fac1= du*u;
608                                         bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
609                                         bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
610                                         bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
611                                         
612                                         /* v extrema */
613                                         bp1= latt_bp(lt, u, 0, w);
614                                         bp2= latt_bp(lt, u, lt->pntsv-1, w);
615                                         
616                                         fac1= dv*v;
617                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
618                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
619                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
620                                         
621                                         /* w extrema */
622                                         bp1= latt_bp(lt, u, v, 0);
623                                         bp2= latt_bp(lt, u, v, lt->pntsw-1);
624                                         
625                                         fac1= dw*w;
626                                         bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
627                                         bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
628                                         bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
629                                         
630                                         VecMulf(bp->vec, 0.3333333f);
631                                         
632                                 }
633                         }
634                         
635                 }
636                 
637         }
638         
639 }