2 * lattice.c MIXED MODEL
6 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
25 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26 * All rights reserved.
28 * The Original Code is: all of this file.
30 * Contributor(s): none yet.
32 * ***** END GPL/BL DUAL LICENSE BLOCK *****
40 #include "MEM_guardedalloc.h"
42 #include "BLI_blenlib.h"
43 #include "BLI_arithb.h"
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"
54 #include "BKE_utildefines.h"
55 #include "BKE_armature.h"
56 #include "BKE_library.h"
57 #include "BKE_global.h"
59 #include "BKE_screen.h"
60 #include "BKE_displist.h"
61 #include "BKE_lattice.h"
63 #include "BKE_object.h"
66 Lattice *editLatt=0, *deformLatt=0;
68 float *latticedata=0, latmat[4][4];
71 void resizelattice(Lattice *lt)
75 float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
79 lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
83 while(lt->pntsu*lt->pntsv*lt->pntsw > 32000) {
84 if( lt->pntsu>=lt->pntsv && lt->pntsu>=lt->pntsw) lt->pntsu--;
85 else if( lt->pntsv>=lt->pntsu && lt->pntsv>=lt->pntsw) lt->pntsv--;
89 calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
90 calc_lat_fudu(lt->flag, lt->pntsv, &fv, &dv);
91 calc_lat_fudu(lt->flag, lt->pntsw, &fw, &dw);
94 for(w=0; w<lt->pntsw; w++) {
96 for(v=0; v<lt->pntsv; v++) {
98 for(u=0; u<lt->pntsu; u++, bp++) {
99 VECCOPY(bp->vec, vec);
108 Lattice *add_lattice()
112 lt= alloc_libblock(&G.main->latt, ID_LT, "Lattice");
114 lt->pntsu=lt->pntsv=lt->pntsw= 2;
117 lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
120 lt->def= MEM_callocN(sizeof(BPoint), "lattvert");
122 resizelattice(lt); /* maakt een regelmatige lattice */
127 Lattice *copy_lattice(Lattice *lt)
131 ltn= copy_libblock(lt);
132 ltn->def= MEM_dupallocN(lt->def);
134 id_us_plus((ID *)ltn->ipo);
136 ltn->key= copy_key(ltn->key);
137 if(ltn->key) ltn->key->from= (ID *)ltn;
142 void free_lattice(Lattice *lt)
144 if(lt->def) MEM_freeN(lt->def);
148 void make_local_lattice(Lattice *lt)
154 /* - zijn er alleen lib users: niet doen
155 * - zijn er alleen locale users: flag zetten
159 if(lt->id.lib==0) return;
162 lt->id.flag= LIB_LOCAL;
163 new_id(0, (ID *)lt, 0);
167 ob= G.main->object.first;
170 if(ob->id.lib) lib= 1;
176 if(local && lib==0) {
178 lt->id.flag= LIB_LOCAL;
179 new_id(0, (ID *)lt, 0);
181 else if(local && lib) {
182 ltn= copy_lattice(lt);
185 ob= G.main->object.first;
202 void calc_lat_fudu(int flag, int res, float *fu, float *du)
209 else if(flag & LT_GRID) {
220 void init_latt_deform(Object *oblatt, Object *ob)
222 /* we maken een array met alle verschillen */
224 float *fp, imat[4][4];
225 float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
228 if(oblatt==G.obedit) deformLatt= editLatt;
229 else deformLatt= oblatt->data;
231 fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
235 if(ob) where_is_object(ob);
237 /* bijv bij particle systeem: ob==0 */
239 /* in deformspace, matrix berekenen */
240 Mat4Invert(latmat, oblatt->obmat);
242 /* terug: in deform array verwerken */
243 Mat4Invert(imat, latmat);
246 /* in deformspace, matrix berekenen */
247 Mat4Invert(imat, oblatt->obmat);
248 Mat4MulMat4(latmat, ob->obmat, imat);
250 /* terug: in deform array verwerken */
251 Mat4Invert(imat, latmat);
253 calc_lat_fudu(deformLatt->flag, deformLatt->pntsu, &fu, &du);
254 calc_lat_fudu(deformLatt->flag, deformLatt->pntsv, &fv, &dv);
255 calc_lat_fudu(deformLatt->flag, deformLatt->pntsw, &fw, &dw);
257 /* we berekenen hier steeds de u v w lattice coordinaten, weinig reden ze te onthouden */
260 for(w=0; w<deformLatt->pntsw; w++) {
262 for(v=0; v<deformLatt->pntsv; v++) {
264 for(u=0; u<deformLatt->pntsu; u++, bp++) {
266 VecSubf(fp, bp->vec, vec);
267 Mat4Mul3Vecfl(imat, fp);
278 void calc_latt_deform(float *co)
281 float fu, du, u, v, w, tu[4], tv[4], tw[4];
282 float *fpw, *fpv, *fpu, vec[3];
283 int ui, vi, wi, uu, vv, ww;
285 if(latticedata==0) return;
287 lt= deformLatt; /* kortere notatie! */
289 /* co is in lokale coords, met latmat behandelen */
292 Mat4MulVecfl(latmat, vec);
297 calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
301 set_four_ipo(u, tu, lt->typeu);
304 tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
309 calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du);
313 set_four_ipo(v, tv, lt->typev);
316 tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
321 calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du);
325 set_four_ipo(w, tw, lt->typew);
328 tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
332 for(ww= wi-1; ww<=wi+2; ww++) {
337 if(ww<lt->pntsw) fpw= latticedata + 3*ww*lt->pntsu*lt->pntsv;
338 else fpw= latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
340 else fpw= latticedata;
342 for(vv= vi-1; vv<=vi+2; vv++) {
347 if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
348 else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
352 for(uu= ui-1; uu<=ui+2; uu++) {
357 if(uu<lt->pntsu) fpu= fpv + 3*uu;
358 else fpu= fpv + 3*(lt->pntsu-1);
374 void end_latt_deform()
377 MEM_freeN(latticedata);
382 int object_deform(Object *ob)
391 if(ob->parent==0) return 0;
393 /* altijd proberen in deze fie de hele deform te doen: apply! */
395 if(ob->parent->type==OB_LATTICE) {
397 init_latt_deform(ob->parent, ob);
399 if(ob->type==OB_MESH) {
402 dl= find_displist_create(&ob->disp, DL_VERTS);
405 if(dl->verts) MEM_freeN(dl->verts);
407 dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
409 for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
410 if(lt_applyflag) calc_latt_deform(mvert->co);
412 VECCOPY(fp, mvert->co);
413 calc_latt_deform(fp);
417 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
427 a= nu->pntsu*nu->pntsv;
430 calc_latt_deform(bp->vec);
438 /* when apply, do this too, looks more interactive */
444 if(dl->type==DL_INDEX3) tot=dl->parts;
445 else tot= dl->nr*dl->parts;
447 for(a=0; a<tot; a++, fp+=3) {
448 calc_latt_deform(fp);
456 boundbox_displist(ob);
460 else if(ob->parent->type==OB_ARMATURE) {
461 if (ob->partype != PARSKEL){
465 init_armature_deform (ob->parent, ob);
471 dl= find_displist_create(&ob->disp, DL_VERTS);
474 if(dl->verts) MEM_freeN(dl->verts);
476 dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
478 for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
480 calc_armature_deform(ob->parent, mvert->co, a);
483 VECCOPY(fp, mvert->co);
484 calc_armature_deform(ob->parent, fp, a);
493 boundbox_displist(ob);
496 else if(ob->parent->type==OB_IKA) {
500 if(ob->partype!=PARSKEL) return 0;
502 ika= ob->parent->data;
503 if(ika->def==0) return 0;
505 init_skel_deform(ob->parent, ob);
507 if(ob->type==OB_MESH) {
510 dl= find_displist_create(&ob->disp, DL_VERTS);
513 if(dl->verts) MEM_freeN(dl->verts);
515 dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
517 for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
518 if(lt_applyflag) calc_skel_deform(ika, mvert->co);
520 VECCOPY(fp, mvert->co);
521 calc_skel_deform(ika, fp);
525 else if ELEM(ob->type, OB_CURVE, OB_SURF) {
535 a= nu->pntsu*nu->pntsv;
538 calc_skel_deform(ika, bp->vec);
546 /* when apply, do this too, looks more interactive */
551 tot= dl->nr*dl->parts;
552 for(a=0; a<tot; a++, fp+=3) {
553 calc_skel_deform(ika, fp);
560 boundbox_displist(ob);
569 BPoint *latt_bp(Lattice *lt, int u, int v, int w)
571 return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
574 void outside_lattice(Lattice *lt)
576 BPoint *bp, *bp1, *bp2;
578 float fac1, du=0.0, dv=0.0, dw=0.0;
582 if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
583 if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
584 if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
586 for(w=0; w<lt->pntsw; w++) {
588 for(v=0; v<lt->pntsv; v++) {
590 for(u=0; u<lt->pntsu; u++, bp++) {
591 if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
598 bp1= latt_bp(lt, 0, v, w);
599 bp2= latt_bp(lt, lt->pntsu-1, v, w);
602 bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
603 bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
604 bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
607 bp1= latt_bp(lt, u, 0, w);
608 bp2= latt_bp(lt, u, lt->pntsv-1, w);
611 bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
612 bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
613 bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
616 bp1= latt_bp(lt, u, v, 0);
617 bp2= latt_bp(lt, u, v, lt->pntsw-1);
620 bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
621 bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
622 bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
624 VecMulf(bp->vec, 0.3333333f);