9a528b541431cb6b45abad6c088f4d0cbd3dc27d
[blender.git] / source / blender / blenkernel / intern / lattice.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/lattice.c
29  *  \ingroup bke
30  */
31
32
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <math.h>
37 #include <stdlib.h>
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_bpath.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45
46 #include "DNA_mesh_types.h"
47 #include "DNA_meshdata_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_lattice_types.h"
51 #include "DNA_curve_types.h"
52 #include "DNA_key_types.h"
53
54 #include "BKE_animsys.h"
55 #include "BKE_anim.h"
56 #include "BKE_cdderivedmesh.h"
57 #include "BKE_displist.h"
58 #include "BKE_global.h"
59 #include "BKE_key.h"
60 #include "BKE_lattice.h"
61 #include "BKE_library.h"
62 #include "BKE_main.h"
63 #include "BKE_mesh.h"
64 #include "BKE_modifier.h"
65
66 #include "BKE_deform.h"
67
68 //XXX #include "BIF_editdeform.h"
69
70 void calc_lat_fudu(int flag, int res, float *fu, float *du)
71 {
72         if(res==1) {
73                 *fu= 0.0;
74                 *du= 0.0;
75         }
76         else if(flag & LT_GRID) {
77                 *fu= -0.5f*(res-1);
78                 *du= 1.0f;
79         }
80         else {
81                 *fu= -1.0f;
82                 *du= 2.0f/(res-1);
83         }
84 }
85
86 void resizelattice(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
87 {
88         BPoint *bp;
89         int i, u, v, w;
90         float fu, fv, fw, uc, vc, wc, du=0.0, dv=0.0, dw=0.0;
91         float *co, (*vertexCos)[3] = NULL;
92         
93         /* vertex weight groups are just freed all for now */
94         if(lt->dvert) {
95                 free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
96                 lt->dvert= NULL;
97         }
98         
99         while(uNew*vNew*wNew > 32000) {
100                 if( uNew>=vNew && uNew>=wNew) uNew--;
101                 else if( vNew>=uNew && vNew>=wNew) vNew--;
102                 else wNew--;
103         }
104
105         vertexCos = MEM_mallocN(sizeof(*vertexCos)*uNew*vNew*wNew, "tmp_vcos");
106
107         calc_lat_fudu(lt->flag, uNew, &fu, &du);
108         calc_lat_fudu(lt->flag, vNew, &fv, &dv);
109         calc_lat_fudu(lt->flag, wNew, &fw, &dw);
110
111                 /* If old size is different then resolution changed in interface,
112                  * try to do clever reinit of points. Pretty simply idea, we just
113                  * deform new verts by old lattice, but scaling them to match old
114                  * size first.
115                  */
116         if (ltOb) {
117                 if (uNew!=1 && lt->pntsu!=1) {
118                         fu = lt->fu;
119                         du = (lt->pntsu-1)*lt->du/(uNew-1);
120                 }
121
122                 if (vNew!=1 && lt->pntsv!=1) {
123                         fv = lt->fv;
124                         dv = (lt->pntsv-1)*lt->dv/(vNew-1);
125                 }
126
127                 if (wNew!=1 && lt->pntsw!=1) {
128                         fw = lt->fw;
129                         dw = (lt->pntsw-1)*lt->dw/(wNew-1);
130                 }
131         }
132
133         co = vertexCos[0];
134         for(w=0,wc=fw; w<wNew; w++,wc+=dw) {
135                 for(v=0,vc=fv; v<vNew; v++,vc+=dv) {
136                         for(u=0,uc=fu; u<uNew; u++,co+=3,uc+=du) {
137                                 co[0] = uc;
138                                 co[1] = vc;
139                                 co[2] = wc;
140                         }
141                 }
142         }
143         
144         if (ltOb) {
145                 float mat[4][4];
146                 int typeu = lt->typeu, typev = lt->typev, typew = lt->typew;
147
148                         /* works best if we force to linear type (endpoints match) */
149                 lt->typeu = lt->typev = lt->typew = KEY_LINEAR;
150
151                         /* prevent using deformed locations */
152                 freedisplist(&ltOb->disp);
153
154                 copy_m4_m4(mat, ltOb->obmat);
155                 unit_m4(ltOb->obmat);
156                 lattice_deform_verts(ltOb, NULL, NULL, vertexCos, uNew*vNew*wNew, NULL);
157                 copy_m4_m4(ltOb->obmat, mat);
158
159                 lt->typeu = typeu;
160                 lt->typev = typev;
161                 lt->typew = typew;
162         }
163
164         lt->fu = fu;
165         lt->fv = fv;
166         lt->fw = fw;
167         lt->du = du;
168         lt->dv = dv;
169         lt->dw = dw;
170
171         lt->pntsu = uNew;
172         lt->pntsv = vNew;
173         lt->pntsw = wNew;
174
175         MEM_freeN(lt->def);
176         lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
177         
178         bp= lt->def;
179         
180         for (i=0; i<lt->pntsu*lt->pntsv*lt->pntsw; i++,bp++) {
181                 copy_v3_v3(bp->vec, vertexCos[i]);
182         }
183
184         MEM_freeN(vertexCos);
185 }
186
187 Lattice *add_lattice(const char *name)
188 {
189         Lattice *lt;
190         
191         lt= alloc_libblock(&G.main->latt, ID_LT, name);
192         
193         lt->flag= LT_GRID;
194         
195         lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
196         
197         lt->def= MEM_callocN(sizeof(BPoint), "lattvert"); /* temporary */
198         resizelattice(lt, 2, 2, 2, NULL);       /* creates a uniform lattice */
199                 
200         return lt;
201 }
202
203 Lattice *copy_lattice(Lattice *lt)
204 {
205         Lattice *ltn;
206
207         ltn= copy_libblock(lt);
208         ltn->def= MEM_dupallocN(lt->def);
209
210         ltn->key= copy_key(ltn->key);
211         if(ltn->key) ltn->key->from= (ID *)ltn;
212         
213         if(lt->dvert) {
214                 int tot= lt->pntsu*lt->pntsv*lt->pntsw;
215                 ltn->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
216                 copy_dverts(ltn->dvert, lt->dvert, tot);
217         }
218
219         ltn->editlatt= NULL;
220
221         return ltn;
222 }
223
224 void free_lattice(Lattice *lt)
225 {
226         if(lt->def) MEM_freeN(lt->def);
227         if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
228         if(lt->editlatt) {
229                 Lattice *editlt= lt->editlatt->latt;
230
231                 if(editlt->def) MEM_freeN(editlt->def);
232                 if(editlt->dvert) free_dverts(editlt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
233
234                 MEM_freeN(editlt);
235                 MEM_freeN(lt->editlatt);
236         }
237         
238         /* free animation data */
239         if (lt->adt) {
240                 BKE_free_animdata(&lt->id);
241                 lt->adt= NULL;
242         }
243 }
244
245
246 void make_local_lattice(Lattice *lt)
247 {
248         Main *bmain= G.main;
249         Object *ob;
250         int is_local= FALSE, is_lib= FALSE;
251
252         /* - only lib users: do nothing
253          * - only local users: set flag
254          * - mixed: make copy
255          */
256         
257         if(lt->id.lib==NULL) return;
258         if(lt->id.us==1) {
259                 id_clear_lib_data(bmain, &lt->id);
260                 return;
261         }
262         
263         for(ob= bmain->object.first; ob && ELEM(FALSE, is_lib, is_local); ob= ob->id.next) {
264                 if(ob->data==lt) {
265                         if(ob->id.lib) is_lib= TRUE;
266                         else is_local= TRUE;
267                 }
268         }
269         
270         if(is_local && is_lib==FALSE) {
271                 id_clear_lib_data(bmain, &lt->id);
272         }
273         else if(is_local && is_lib) {
274                 char *bath_user_data[2]= {bmain->name, lt->id.lib->filepath};
275                 Lattice *ltn= copy_lattice(lt);
276                 ltn->id.us= 0;
277
278                 /* Remap paths of new ID using old library as base. */
279                 bpath_traverse_id(bmain, &ltn->id, bpath_relocate_visitor, 0, bath_user_data);
280
281                 for(ob= bmain->object.first; ob; ob= ob->id.next) {
282                         if(ob->data==lt) {
283                                 if(ob->id.lib==NULL) {
284                                         ob->data= ltn;
285                                         ltn->id.us++;
286                                         lt->id.us--;
287                                 }
288                         }
289                 }
290         }
291 }
292
293 void init_latt_deform(Object *oblatt, Object *ob)
294 {
295                 /* we make an array with all differences */
296         Lattice *lt= oblatt->data;
297         BPoint *bp;
298         DispList *dl = find_displist(&oblatt->disp, DL_VERTS);
299         float *co = dl?dl->verts:NULL;
300         float *fp, imat[4][4];
301         float fu, fv, fw;
302         int u, v, w;
303
304         if(lt->editlatt) lt= lt->editlatt->latt;
305         bp = lt->def;
306         
307         fp= lt->latticedata= MEM_mallocN(sizeof(float)*3*lt->pntsu*lt->pntsv*lt->pntsw, "latticedata");
308         
309                 /* for example with a particle system: ob==0 */
310         if(ob==NULL) {
311                 /* in deformspace, calc matrix  */
312                 invert_m4_m4(lt->latmat, oblatt->obmat);
313         
314                 /* back: put in deform array */
315                 invert_m4_m4(imat, lt->latmat);
316         }
317         else {
318                 /* in deformspace, calc matrix */
319                 invert_m4_m4(imat, oblatt->obmat);
320                 mul_m4_m4m4(lt->latmat, ob->obmat, imat);
321         
322                 /* back: put in deform array */
323                 invert_m4_m4(imat, lt->latmat);
324         }
325         
326         for(w=0,fw=lt->fw; w<lt->pntsw; w++,fw+=lt->dw) {
327                 for(v=0,fv=lt->fv; v<lt->pntsv; v++, fv+=lt->dv) {
328                         for(u=0,fu=lt->fu; u<lt->pntsu; u++, bp++, co+=3, fp+=3, fu+=lt->du) {
329                                 if (dl) {
330                                         fp[0] = co[0] - fu;
331                                         fp[1] = co[1] - fv;
332                                         fp[2] = co[2] - fw;
333                                 } else {
334                                         fp[0] = bp->vec[0] - fu;
335                                         fp[1] = bp->vec[1] - fv;
336                                         fp[2] = bp->vec[2] - fw;
337                                 }
338
339                                 mul_mat3_m4_v3(imat, fp);
340                         }
341                 }
342         }
343 }
344
345 void calc_latt_deform(Object *ob, float *co, float weight)
346 {
347         Lattice *lt= ob->data;
348         float u, v, w, tu[4], tv[4], tw[4];
349         float vec[3];
350         int idx_w, idx_v, idx_u;
351         int ui, vi, wi, uu, vv, ww;
352
353         /* vgroup influence */
354         int defgroup_nr= -1;
355         float co_prev[3], weight_blend= 0.0f;
356         MDeformVert *dvert= lattice_get_deform_verts(ob);
357
358
359         if(lt->editlatt) lt= lt->editlatt->latt;
360         if(lt->latticedata==NULL) return;
361
362         if(lt->vgroup[0] && dvert) {
363                 defgroup_nr= defgroup_name_index(ob, lt->vgroup);
364                 copy_v3_v3(co_prev, co);
365         }
366
367         /* co is in local coords, treat with latmat */
368         mul_v3_m4v3(vec, lt->latmat, co);
369
370         /* u v w coords */
371
372         if(lt->pntsu>1) {
373                 u= (vec[0]-lt->fu)/lt->du;
374                 ui= (int)floor(u);
375                 u -= ui;
376                 key_curve_position_weights(u, tu, lt->typeu);
377         }
378         else {
379                 tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
380                 ui= 0;
381         }
382
383         if(lt->pntsv>1) {
384                 v= (vec[1]-lt->fv)/lt->dv;
385                 vi= (int)floor(v);
386                 v -= vi;
387                 key_curve_position_weights(v, tv, lt->typev);
388         }
389         else {
390                 tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
391                 vi= 0;
392         }
393
394         if(lt->pntsw>1) {
395                 w= (vec[2]-lt->fw)/lt->dw;
396                 wi= (int)floor(w);
397                 w -= wi;
398                 key_curve_position_weights(w, tw, lt->typew);
399         }
400         else {
401                 tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
402                 wi= 0;
403         }
404
405         for(ww= wi-1; ww<=wi+2; ww++) {
406                 w= tw[ww-wi+1];
407
408                 if(w != 0.0f) {
409                         if(ww>0) {
410                                 if(ww<lt->pntsw) idx_w= ww*lt->pntsu*lt->pntsv;
411                                 else idx_w= (lt->pntsw-1)*lt->pntsu*lt->pntsv;
412                         }
413                         else idx_w= 0;
414
415                         for(vv= vi-1; vv<=vi+2; vv++) {
416                                 v= w*tv[vv-vi+1];
417
418                                 if(v != 0.0f) {
419                                         if(vv>0) {
420                                                 if(vv<lt->pntsv) idx_v= idx_w + vv*lt->pntsu;
421                                                 else idx_v= idx_w + (lt->pntsv-1)*lt->pntsu;
422                                         }
423                                         else idx_v= idx_w;
424
425                                         for(uu= ui-1; uu<=ui+2; uu++) {
426                                                 u= weight*v*tu[uu-ui+1];
427
428                                                 if(u != 0.0f) {
429                                                         if(uu>0) {
430                                                                 if(uu<lt->pntsu) idx_u= idx_v + uu;
431                                                                 else idx_u= idx_v + (lt->pntsu-1);
432                                                         }
433                                                         else idx_u= idx_v;
434
435                                                         madd_v3_v3fl(co, &lt->latticedata[idx_u * 3], u);
436
437                                                         if(defgroup_nr != -1)
438                                                                 weight_blend += (u * defvert_find_weight(dvert + idx_u, defgroup_nr));
439                                                 }
440                                         }
441                                 }
442                         }
443                 }
444         }
445
446         if(defgroup_nr != -1)
447                 interp_v3_v3v3(co, co_prev, co, weight_blend);
448
449 }
450
451 void end_latt_deform(Object *ob)
452 {
453         Lattice *lt= ob->data;
454         
455         if(lt->editlatt) lt= lt->editlatt->latt;
456         
457         if(lt->latticedata)
458                 MEM_freeN(lt->latticedata);
459         lt->latticedata= NULL;
460 }
461
462         /* calculations is in local space of deformed object
463            so we store in latmat transform from path coord inside object 
464          */
465 typedef struct {
466         float dmin[3], dmax[3], dsize, dloc[3];
467         float curvespace[4][4], objectspace[4][4], objectspace3[3][3];
468         int no_rot_axis;
469 } CurveDeform;
470
471 static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc)
472 {
473         invert_m4_m4(ob->imat, ob->obmat);
474         mul_m4_m4m4(cd->objectspace, par->obmat, ob->imat);
475         invert_m4_m4(cd->curvespace, cd->objectspace);
476         copy_m3_m4(cd->objectspace3, cd->objectspace);
477         
478         // offset vector for 'no smear'
479         if(dloc) {
480                 invert_m4_m4(par->imat, par->obmat);
481                 mul_v3_m4v3(cd->dloc, par->imat, ob->obmat[3]);
482         }
483         else {
484                 cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f;
485         }
486         
487         cd->no_rot_axis= 0;
488 }
489
490 /* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
491 static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius)    /* returns OK */
492 {
493         Curve *cu= ob->data;
494         BevList *bl;
495         float ctime1;
496         int cycl=0;
497         
498         /* test for cyclic */
499         bl= cu->bev.first;
500         if (!bl->nr) return 0;
501         if(bl && bl->poly> -1) cycl= 1;
502
503         if(cycl==0) {
504                 ctime1= CLAMPIS(ctime, 0.0f, 1.0f);
505         }
506         else ctime1= ctime;
507         
508         /* vec needs 4 items */
509         if(where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
510                 
511                 if(cycl==0) {
512                         Path *path= cu->path;
513                         float dvec[3];
514                         
515                         if(ctime < 0.0f) {
516                                 sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec);
517                                 mul_v3_fl(dvec, ctime*(float)path->len);
518                                 add_v3_v3(vec, dvec);
519                                 if(quat) copy_qt_qt(quat, path->data[0].quat);
520                                 if(radius) *radius= path->data[0].radius;
521                         }
522                         else if(ctime > 1.0f) {
523                                 sub_v3_v3v3(dvec, path->data[path->len-1].vec, path->data[path->len-2].vec);
524                                 mul_v3_fl(dvec, (ctime-1.0f)*(float)path->len);
525                                 add_v3_v3(vec, dvec);
526                                 if(quat) copy_qt_qt(quat, path->data[path->len-1].quat);
527                                 if(radius) *radius= path->data[path->len-1].radius;
528                                 /* weight - not used but could be added */
529                         }
530                 }
531                 return 1;
532         }
533         return 0;
534 }
535
536         /* for each point, rotate & translate to curve */
537         /* use path, since it has constant distances */
538         /* co: local coord, result local too */
539         /* returns quaternion for rotation, using cd->no_rot_axis */
540         /* axis is using another define!!! */
541 static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp)
542 {
543         Curve *cu= par->data;
544         float fac, loc[4], dir[3], new_quat[4], radius;
545         short /*upflag, */ index;
546
547         index= axis-1;
548         if(index>2)
549                 index -= 3; /* negative  */
550
551         /* to be sure, mostly after file load */
552         if(cu->path==NULL) {
553                 makeDispListCurveTypes(scene, par, 0);
554                 if(cu->path==NULL) return 0;    // happens on append...
555         }
556         
557         /* options */
558         if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
559                 if(cu->flag & CU_STRETCH)
560                         fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
561                 else
562                         fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist);
563         }
564         else {
565                 if(cu->flag & CU_STRETCH)
566                         fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
567                 else
568                         fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
569         }
570         
571 #if 0 // XXX old animation system
572         /* we want the ipo to work on the default 100 frame range, because there's no  
573            actual time involved in path position */
574         // huh? by WHY!!!!???? - Aligorith
575         if(cu->ipo) {
576                 fac*= 100.0f;
577                 if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0)
578                         fac/= 100.0;
579         }
580 #endif // XXX old animation system
581         
582         if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) {      /* returns OK */
583                 float quat[4], cent[3];
584
585 #if 0   // XXX - 2.4x Z-Up, Now use bevel tilt.
586                 if(cd->no_rot_axis)     /* set by caller */
587                         dir[cd->no_rot_axis-1]= 0.0f;
588                 
589                 /* -1 for compatibility with old track defines */
590                 vec_to_quat( quat,dir, axis-1, upflag);
591                 
592                 /* the tilt */
593                 if(loc[3]!=0.0) {
594                         normalize_v3(dir);
595                         q[0]= (float)cos(0.5*loc[3]);
596                         fac= (float)sin(0.5*loc[3]);
597                         q[1]= -fac*dir[0];
598                         q[2]= -fac*dir[1];
599                         q[3]= -fac*dir[2];
600                         mul_qt_qtqt(quat, q, quat);
601                 }
602 #endif
603
604                 if(cd->no_rot_axis) {   /* set by caller */
605
606                         /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than
607                          * changing the axis before calculating the tilt but serves much the same purpose */
608                         float dir_flat[3]={0,0,0}, q[4];
609                         copy_v3_v3(dir_flat, dir);
610                         dir_flat[cd->no_rot_axis-1]= 0.0f;
611
612                         normalize_v3(dir);
613                         normalize_v3(dir_flat);
614
615                         rotation_between_vecs_to_quat(q, dir, dir_flat); /* Could this be done faster? */
616
617                         mul_qt_qtqt(new_quat, q, new_quat);
618                 }
619
620
621                 /* Logic for 'cent' orientation *
622                  *
623                  * The way 'co' is copied to 'cent' may seem to have no meaning, but it does.
624                  *
625                  * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark.
626                  * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise
627                  * Notice X,Y,Z Up all have light colors and each ordered CCW.
628                  *
629                  * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
630                  *
631                  * note: moved functions into quat_apply_track/vec_apply_track
632                  * */
633                 copy_qt_qt(quat, new_quat);
634                 copy_v3_v3(cent, co);
635
636                 /* zero the axis which is not used,
637                  * the big block of text above now applies to these 3 lines */
638                 quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */
639                 vec_apply_track(cent, axis-1);
640                 cent[axis < 4 ? axis-1 : axis-4]= 0.0f;
641
642
643                 /* scale if enabled */
644                 if(cu->flag & CU_PATH_RADIUS)
645                         mul_v3_fl(cent, radius);
646                 
647                 /* local rotation */
648                 normalize_qt(quat);
649                 mul_qt_v3(quat, cent);
650
651                 /* translation */
652                 add_v3_v3v3(co, cent, loc);
653
654                 if(quatp)
655                         copy_qt_qt(quatp, quat);
656
657                 return 1;
658         }
659         return 0;
660 }
661
662 void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, char *vgroup, short defaxis)
663 {
664         Curve *cu;
665         int a, flag;
666         CurveDeform cd;
667         int use_vgroups;
668
669         if(cuOb->type != OB_CURVE)
670                 return;
671
672         cu = cuOb->data;
673         flag = cu->flag;
674         cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
675
676         init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0);
677
678         /* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */
679         if(defaxis < 3) {
680                 cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
681                 cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
682         }
683         else {
684                 /* negative, these bounds give a good rest position */
685                 cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= -1.0f;
686                 cd.dmax[0]= cd.dmax[1]= cd.dmax[2]=  0.0f;
687         }
688         
689         /* check whether to use vertex groups (only possible if target is a Mesh)
690          * we want either a Mesh with no derived data, or derived data with
691          * deformverts
692          */
693         if(target && target->type==OB_MESH) {
694                 /* if there's derived data without deformverts, don't use vgroups */
695                 if(dm && !dm->getVertData(dm, 0, CD_MDEFORMVERT))
696                         use_vgroups = 0;
697                 else
698                         use_vgroups = 1;
699         } else
700                 use_vgroups = 0;
701         
702         if(vgroup && vgroup[0] && use_vgroups) {
703                 Mesh *me= target->data;
704                 int index= defgroup_name_index(target, vgroup);
705
706                 if(index != -1 && (me->dvert || dm)) {
707                         MDeformVert *dvert = me->dvert;
708                         float vec[3];
709                         float weight;
710         
711
712                         if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
713                                 /* dummy bounds */
714                                 cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
715                                 cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
716                                 
717                                 dvert = me->dvert;
718                                 for(a = 0; a < numVerts; a++, dvert++) {
719                                         if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
720                                         weight= defvert_find_weight(dvert, index);
721         
722                                         if(weight > 0.0f) {
723                                                 mul_m4_v3(cd.curvespace, vertexCos[a]);
724                                                 copy_v3_v3(vec, vertexCos[a]);
725                                                 calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
726                                                 interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
727                                                 mul_m4_v3(cd.objectspace, vertexCos[a]);
728                                         }
729                                 }
730                         }
731                         else {
732                                 /* set mesh min/max bounds */
733                                 INIT_MINMAX(cd.dmin, cd.dmax);
734         
735                                 for(a = 0; a < numVerts; a++, dvert++) {
736                                         if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
737                                         
738                                         if(defvert_find_weight(dvert, index) > 0.0f) {
739                                                 mul_m4_v3(cd.curvespace, vertexCos[a]);
740                                                 DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
741                                         }
742                                 }
743         
744                                 dvert = me->dvert;
745                                 for(a = 0; a < numVerts; a++, dvert++) {
746                                         if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
747                                         
748                                         weight= defvert_find_weight(dvert, index);
749         
750                                         if(weight > 0.0f) {
751                                                 copy_v3_v3(vec, vertexCos[a]);
752                                                 calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
753                                                 interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
754                                                 mul_m4_v3(cd.objectspace, vertexCos[a]);
755                                         }
756                                 }
757                         }
758                 }
759         }
760         else {
761                 if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
762                         for(a = 0; a < numVerts; a++) {
763                                 mul_m4_v3(cd.curvespace, vertexCos[a]);
764                                 calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
765                                 mul_m4_v3(cd.objectspace, vertexCos[a]);
766                         }
767                 }
768                 else {
769                         /* set mesh min max bounds */
770                         INIT_MINMAX(cd.dmin, cd.dmax);
771                                 
772                         for(a = 0; a < numVerts; a++) {
773                                 mul_m4_v3(cd.curvespace, vertexCos[a]);
774                                 DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
775                         }
776         
777                         for(a = 0; a < numVerts; a++) {
778                                 calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
779                                 mul_m4_v3(cd.objectspace, vertexCos[a]);
780                         }
781                 }
782         }
783         cu->flag = flag;
784 }
785
786 /* input vec and orco = local coord in armature space */
787 /* orco is original not-animated or deformed reference point */
788 /* result written in vec and mat */
789 void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco, float *vec, float mat[][3], int no_rot_axis)
790 {
791         CurveDeform cd;
792         float quat[4];
793         
794         if(cuOb->type != OB_CURVE) {
795                 unit_m3(mat);
796                 return;
797         }
798
799         init_curve_deform(cuOb, target, &cd, 0);        /* 0 no dloc */
800         cd.no_rot_axis= no_rot_axis;                            /* option to only rotate for XY, for example */
801         
802         copy_v3_v3(cd.dmin, orco);
803         copy_v3_v3(cd.dmax, orco);
804
805         mul_m4_v3(cd.curvespace, vec);
806         
807         if(calc_curve_deform(scene, cuOb, vec, target->trackflag+1, &cd, quat)) {
808                 float qmat[3][3];
809                 
810                 quat_to_mat3( qmat,quat);
811                 mul_m3_m3m3(mat, qmat, cd.objectspace3);
812         }
813         else
814                 unit_m3(mat);
815         
816         mul_m4_v3(cd.objectspace, vec);
817
818 }
819
820 void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
821                                                   float (*vertexCos)[3], int numVerts, char *vgroup)
822 {
823         int a;
824         int use_vgroups;
825
826         if(laOb->type != OB_LATTICE)
827                 return;
828
829         init_latt_deform(laOb, target);
830
831         /* check whether to use vertex groups (only possible if target is a Mesh)
832          * we want either a Mesh with no derived data, or derived data with
833          * deformverts
834          */
835         if(target && target->type==OB_MESH) {
836                 /* if there's derived data without deformverts, don't use vgroups */
837                 if(dm && !dm->getVertData(dm, 0, CD_MDEFORMVERT))
838                         use_vgroups = 0;
839                 else
840                         use_vgroups = 1;
841         } else
842                 use_vgroups = 0;
843         
844         if(vgroup && vgroup[0] && use_vgroups) {
845                 Mesh *me = target->data;
846                 int index = defgroup_name_index(target, vgroup);
847                 float weight;
848
849                 if(index >= 0 && (me->dvert || dm)) {
850                         MDeformVert *dvert = me->dvert;
851                         
852                         for(a = 0; a < numVerts; a++, dvert++) {
853                                 if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
854
855                                 weight= defvert_find_weight(dvert, index);
856
857                                 if(weight > 0.0f)
858                                         calc_latt_deform(laOb, vertexCos[a], weight);
859                         }
860                 }
861         } else {
862                 for(a = 0; a < numVerts; a++) {
863                         calc_latt_deform(laOb, vertexCos[a], 1.0f);
864                 }
865         }
866         end_latt_deform(laOb);
867 }
868
869 int object_deform_mball(Object *ob, ListBase *dispbase)
870 {
871         if(ob->parent && ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
872                 DispList *dl;
873
874                 for (dl=dispbase->first; dl; dl=dl->next) {
875                         lattice_deform_verts(ob->parent, ob, NULL,
876                                                                  (float(*)[3]) dl->verts, dl->nr, NULL);
877                 }
878
879                 return 1;
880         } else {
881                 return 0;
882         }
883 }
884
885 static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
886 {
887         return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
888 }
889
890 void outside_lattice(Lattice *lt)
891 {
892         BPoint *bp, *bp1, *bp2;
893         int u, v, w;
894         float fac1, du=0.0, dv=0.0, dw=0.0;
895
896         if(lt->flag & LT_OUTSIDE) {
897                 bp= lt->def;
898
899                 if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
900                 if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
901                 if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
902                         
903                 for(w=0; w<lt->pntsw; w++) {
904                         
905                         for(v=0; v<lt->pntsv; v++) {
906                         
907                                 for(u=0; u<lt->pntsu; u++, bp++) {
908                                         if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
909                                         else {
910                                         
911                                                 bp->hide= 1;
912                                                 bp->f1 &= ~SELECT;
913                                                 
914                                                 /* u extrema */
915                                                 bp1= latt_bp(lt, 0, v, w);
916                                                 bp2= latt_bp(lt, lt->pntsu-1, v, w);
917                                                 
918                                                 fac1= du*u;
919                                                 bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
920                                                 bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
921                                                 bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
922                                                 
923                                                 /* v extrema */
924                                                 bp1= latt_bp(lt, u, 0, w);
925                                                 bp2= latt_bp(lt, u, lt->pntsv-1, w);
926                                                 
927                                                 fac1= dv*v;
928                                                 bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
929                                                 bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
930                                                 bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
931                                                 
932                                                 /* w extrema */
933                                                 bp1= latt_bp(lt, u, v, 0);
934                                                 bp2= latt_bp(lt, u, v, lt->pntsw-1);
935                                                 
936                                                 fac1= dw*w;
937                                                 bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
938                                                 bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
939                                                 bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
940                                                 
941                                                 mul_v3_fl(bp->vec, 0.3333333f);
942                                                 
943                                         }
944                                 }
945                                 
946                         }
947                         
948                 }
949         }
950         else {
951                 bp= lt->def;
952
953                 for(w=0; w<lt->pntsw; w++)
954                         for(v=0; v<lt->pntsv; v++)
955                                 for(u=0; u<lt->pntsu; u++, bp++)
956                                         bp->hide= 0;
957         }
958 }
959
960 float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]
961 {
962         Lattice *lt = ob->data;
963         int i, numVerts;
964         float (*vertexCos)[3];
965
966         if(lt->editlatt) lt= lt->editlatt->latt;
967         numVerts = *numVerts_r = lt->pntsu*lt->pntsv*lt->pntsw;
968         
969         vertexCos = MEM_mallocN(sizeof(*vertexCos)*numVerts,"lt_vcos");
970         
971         for (i=0; i<numVerts; i++) {
972                 copy_v3_v3(vertexCos[i], lt->def[i].vec);
973         }
974
975         return vertexCos;
976 }
977
978 void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3])
979 {
980         Lattice *lt = ob->data;
981         int i, numVerts = lt->pntsu*lt->pntsv*lt->pntsw;
982
983         for (i=0; i<numVerts; i++) {
984                 copy_v3_v3(lt->def[i].vec, vertexCos[i]);
985         }
986 }
987
988 void lattice_calc_modifiers(Scene *scene, Object *ob)
989 {
990         Lattice *lt= ob->data;
991         ModifierData *md = modifiers_getVirtualModifierList(ob);
992         float (*vertexCos)[3] = NULL;
993         int numVerts, editmode = (lt->editlatt!=NULL);
994
995         freedisplist(&ob->disp);
996
997         for (; md; md=md->next) {
998                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
999
1000                 md->scene= scene;
1001                 
1002                 if (!(md->mode&eModifierMode_Realtime)) continue;
1003                 if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
1004                 if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
1005                 if (mti->type!=eModifierTypeType_OnlyDeform) continue;
1006
1007                 if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
1008                 mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
1009         }
1010
1011         /* always displist to make this work like derivedmesh */
1012         if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
1013         
1014         {
1015                 DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
1016                 dl->type = DL_VERTS;
1017                 dl->parts = 1;
1018                 dl->nr = numVerts;
1019                 dl->verts = (float*) vertexCos;
1020                 
1021                 BLI_addtail(&ob->disp, dl);
1022         }
1023 }
1024
1025 struct MDeformVert* lattice_get_deform_verts(struct Object *oblatt)
1026 {
1027         Lattice *lt = (Lattice*)oblatt->data;
1028         BLI_assert(oblatt->type == OB_LATTICE);
1029         if(lt->editlatt) lt= lt->editlatt->latt;
1030         return lt->dvert;
1031 }