1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup bke
22  */
23 
24 #include <math.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "MEM_guardedalloc.h"
30 
31 #include "BLI_bitmap.h"
32 #include "BLI_listbase.h"
33 #include "BLI_math.h"
34 #include "BLI_utildefines.h"
35 
36 #include "BLT_translation.h"
37 
38 /* Allow using deprecated functionality for .blend file I/O. */
39 #define DNA_DEPRECATED_ALLOW
40 
41 #include "DNA_curve_types.h"
42 #include "DNA_defaults.h"
43 #include "DNA_key_types.h"
44 #include "DNA_lattice_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
48 
49 #include "BKE_anim_data.h"
50 #include "BKE_curve.h"
51 #include "BKE_deform.h"
52 #include "BKE_displist.h"
53 #include "BKE_idtype.h"
54 #include "BKE_lattice.h"
55 #include "BKE_lib_id.h"
56 #include "BKE_lib_query.h"
57 #include "BKE_main.h"
58 #include "BKE_modifier.h"
59 #include "BKE_object.h"
60 
61 #include "DEG_depsgraph_query.h"
62 
63 #include "BLO_read_write.h"
64 
lattice_init_data(ID * id)65 static void lattice_init_data(ID *id)
66 {
67   Lattice *lattice = (Lattice *)id;
68 
69   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(lattice, id));
70 
71   MEMCPY_STRUCT_AFTER(lattice, DNA_struct_default_get(Lattice), id);
72 
73   lattice->def = MEM_callocN(sizeof(BPoint), "lattvert"); /* temporary */
74   BKE_lattice_resize(lattice, 2, 2, 2, NULL);             /* creates a uniform lattice */
75 }
76 
lattice_copy_data(Main * bmain,ID * id_dst,const ID * id_src,const int flag)77 static void lattice_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
78 {
79   Lattice *lattice_dst = (Lattice *)id_dst;
80   const Lattice *lattice_src = (const Lattice *)id_src;
81 
82   lattice_dst->def = MEM_dupallocN(lattice_src->def);
83 
84   if (lattice_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
85     BKE_id_copy_ex(bmain, &lattice_src->key->id, (ID **)&lattice_dst->key, flag);
86     /* XXX This is not nice, we need to make BKE_id_copy_ex fully re-entrant... */
87     lattice_dst->key->from = &lattice_dst->id;
88   }
89 
90   if (lattice_src->dvert) {
91     int tot = lattice_src->pntsu * lattice_src->pntsv * lattice_src->pntsw;
92     lattice_dst->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
93     BKE_defvert_array_copy(lattice_dst->dvert, lattice_src->dvert, tot);
94   }
95 
96   lattice_dst->editlatt = NULL;
97 }
98 
lattice_free_data(ID * id)99 static void lattice_free_data(ID *id)
100 {
101   Lattice *lattice = (Lattice *)id;
102 
103   BKE_lattice_batch_cache_free(lattice);
104 
105   MEM_SAFE_FREE(lattice->def);
106   if (lattice->dvert) {
107     BKE_defvert_array_free(lattice->dvert, lattice->pntsu * lattice->pntsv * lattice->pntsw);
108     lattice->dvert = NULL;
109   }
110   if (lattice->editlatt) {
111     Lattice *editlt = lattice->editlatt->latt;
112 
113     if (editlt->def) {
114       MEM_freeN(editlt->def);
115     }
116     if (editlt->dvert) {
117       BKE_defvert_array_free(editlt->dvert, lattice->pntsu * lattice->pntsv * lattice->pntsw);
118     }
119 
120     MEM_freeN(editlt);
121     MEM_freeN(lattice->editlatt);
122     lattice->editlatt = NULL;
123   }
124 }
125 
lattice_foreach_id(ID * id,LibraryForeachIDData * data)126 static void lattice_foreach_id(ID *id, LibraryForeachIDData *data)
127 {
128   Lattice *lattice = (Lattice *)id;
129   BKE_LIB_FOREACHID_PROCESS(data, lattice->key, IDWALK_CB_USER);
130 }
131 
lattice_blend_write(BlendWriter * writer,ID * id,const void * id_address)132 static void lattice_blend_write(BlendWriter *writer, ID *id, const void *id_address)
133 {
134   Lattice *lt = (Lattice *)id;
135   if (lt->id.us > 0 || BLO_write_is_undo(writer)) {
136     /* Clean up, important in undo case to reduce false detection of changed datablocks. */
137     lt->editlatt = NULL;
138     lt->batch_cache = NULL;
139 
140     /* write LibData */
141     BLO_write_id_struct(writer, Lattice, id_address, &lt->id);
142     BKE_id_blend_write(writer, &lt->id);
143 
144     /* write animdata */
145     if (lt->adt) {
146       BKE_animdata_blend_write(writer, lt->adt);
147     }
148 
149     /* direct data */
150     BLO_write_struct_array(writer, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def);
151 
152     BKE_defvert_blend_write(writer, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
153   }
154 }
155 
lattice_blend_read_data(BlendDataReader * reader,ID * id)156 static void lattice_blend_read_data(BlendDataReader *reader, ID *id)
157 {
158   Lattice *lt = (Lattice *)id;
159   BLO_read_data_address(reader, &lt->def);
160 
161   BLO_read_data_address(reader, &lt->dvert);
162   BKE_defvert_blend_read(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
163 
164   lt->editlatt = NULL;
165   lt->batch_cache = NULL;
166 
167   BLO_read_data_address(reader, &lt->adt);
168   BKE_animdata_blend_read_data(reader, lt->adt);
169 }
170 
lattice_blend_read_lib(BlendLibReader * reader,ID * id)171 static void lattice_blend_read_lib(BlendLibReader *reader, ID *id)
172 {
173   Lattice *lt = (Lattice *)id;
174   BLO_read_id_address(reader, lt->id.lib, &lt->ipo);  // XXX deprecated - old animation system
175   BLO_read_id_address(reader, lt->id.lib, &lt->key);
176 }
177 
lattice_blend_read_expand(BlendExpander * expander,ID * id)178 static void lattice_blend_read_expand(BlendExpander *expander, ID *id)
179 {
180   Lattice *lt = (Lattice *)id;
181   BLO_expand(expander, lt->ipo);  // XXX deprecated - old animation system
182   BLO_expand(expander, lt->key);
183 }
184 
185 IDTypeInfo IDType_ID_LT = {
186     .id_code = ID_LT,
187     .id_filter = FILTER_ID_LT,
188     .main_listbase_index = INDEX_ID_LT,
189     .struct_size = sizeof(Lattice),
190     .name = "Lattice",
191     .name_plural = "lattices",
192     .translation_context = BLT_I18NCONTEXT_ID_LATTICE,
193     .flags = 0,
194 
195     .init_data = lattice_init_data,
196     .copy_data = lattice_copy_data,
197     .free_data = lattice_free_data,
198     .make_local = NULL,
199     .foreach_id = lattice_foreach_id,
200     .foreach_cache = NULL,
201 
202     .blend_write = lattice_blend_write,
203     .blend_read_data = lattice_blend_read_data,
204     .blend_read_lib = lattice_blend_read_lib,
205     .blend_read_expand = lattice_blend_read_expand,
206 };
207 
BKE_lattice_index_from_uvw(Lattice * lt,const int u,const int v,const int w)208 int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w)
209 {
210   const int totu = lt->pntsu;
211   const int totv = lt->pntsv;
212 
213   return (w * (totu * totv) + (v * totu) + u);
214 }
215 
BKE_lattice_index_to_uvw(Lattice * lt,const int index,int * r_u,int * r_v,int * r_w)216 void BKE_lattice_index_to_uvw(Lattice *lt, const int index, int *r_u, int *r_v, int *r_w)
217 {
218   const int totu = lt->pntsu;
219   const int totv = lt->pntsv;
220 
221   *r_u = (index % totu);
222   *r_v = (index / totu) % totv;
223   *r_w = (index / (totu * totv));
224 }
225 
BKE_lattice_index_flip(Lattice * lt,const int index,const bool flip_u,const bool flip_v,const bool flip_w)226 int BKE_lattice_index_flip(
227     Lattice *lt, const int index, const bool flip_u, const bool flip_v, const bool flip_w)
228 {
229   int u, v, w;
230 
231   BKE_lattice_index_to_uvw(lt, index, &u, &v, &w);
232 
233   if (flip_u) {
234     u = (lt->pntsu - 1) - u;
235   }
236 
237   if (flip_v) {
238     v = (lt->pntsv - 1) - v;
239   }
240 
241   if (flip_w) {
242     w = (lt->pntsw - 1) - w;
243   }
244 
245   return BKE_lattice_index_from_uvw(lt, u, v, w);
246 }
247 
BKE_lattice_bitmap_from_flag(Lattice * lt,BLI_bitmap * bitmap,const uint8_t flag,const bool clear,const bool respecthide)248 void BKE_lattice_bitmap_from_flag(
249     Lattice *lt, BLI_bitmap *bitmap, const uint8_t flag, const bool clear, const bool respecthide)
250 {
251   const unsigned int tot = lt->pntsu * lt->pntsv * lt->pntsw;
252   BPoint *bp;
253 
254   bp = lt->def;
255   for (int i = 0; i < tot; i++, bp++) {
256     if ((bp->f1 & flag) && (!respecthide || !bp->hide)) {
257       BLI_BITMAP_ENABLE(bitmap, i);
258     }
259     else {
260       if (clear) {
261         BLI_BITMAP_DISABLE(bitmap, i);
262       }
263     }
264   }
265 }
266 
calc_lat_fudu(int flag,int res,float * r_fu,float * r_du)267 void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du)
268 {
269   if (res == 1) {
270     *r_fu = 0.0;
271     *r_du = 0.0;
272   }
273   else if (flag & LT_GRID) {
274     *r_fu = -0.5f * (res - 1);
275     *r_du = 1.0f;
276   }
277   else {
278     *r_fu = -1.0f;
279     *r_du = 2.0f / (res - 1);
280   }
281 }
282 
BKE_lattice_resize(Lattice * lt,int uNew,int vNew,int wNew,Object * ltOb)283 void BKE_lattice_resize(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
284 {
285   BPoint *bp;
286   int i, u, v, w;
287   float fu, fv, fw, uc, vc, wc, du = 0.0, dv = 0.0, dw = 0.0;
288   float *co, (*vert_coords)[3] = NULL;
289 
290   /* vertex weight groups are just freed all for now */
291   if (lt->dvert) {
292     BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
293     lt->dvert = NULL;
294   }
295 
296   while (uNew * vNew * wNew > 32000) {
297     if (uNew >= vNew && uNew >= wNew) {
298       uNew--;
299     }
300     else if (vNew >= uNew && vNew >= wNew) {
301       vNew--;
302     }
303     else {
304       wNew--;
305     }
306   }
307 
308   vert_coords = MEM_mallocN(sizeof(*vert_coords) * uNew * vNew * wNew, "tmp_vcos");
309 
310   calc_lat_fudu(lt->flag, uNew, &fu, &du);
311   calc_lat_fudu(lt->flag, vNew, &fv, &dv);
312   calc_lat_fudu(lt->flag, wNew, &fw, &dw);
313 
314   /* If old size is different than resolution changed in interface,
315    * try to do clever reinit of points. Pretty simply idea, we just
316    * deform new verts by old lattice, but scaling them to match old
317    * size first.
318    */
319   if (ltOb) {
320     if (uNew != 1 && lt->pntsu != 1) {
321       fu = lt->fu;
322       du = (lt->pntsu - 1) * lt->du / (uNew - 1);
323     }
324 
325     if (vNew != 1 && lt->pntsv != 1) {
326       fv = lt->fv;
327       dv = (lt->pntsv - 1) * lt->dv / (vNew - 1);
328     }
329 
330     if (wNew != 1 && lt->pntsw != 1) {
331       fw = lt->fw;
332       dw = (lt->pntsw - 1) * lt->dw / (wNew - 1);
333     }
334   }
335 
336   co = vert_coords[0];
337   for (w = 0, wc = fw; w < wNew; w++, wc += dw) {
338     for (v = 0, vc = fv; v < vNew; v++, vc += dv) {
339       for (u = 0, uc = fu; u < uNew; u++, co += 3, uc += du) {
340         co[0] = uc;
341         co[1] = vc;
342         co[2] = wc;
343       }
344     }
345   }
346 
347   if (ltOb) {
348     float mat[4][4];
349     int typeu = lt->typeu, typev = lt->typev, typew = lt->typew;
350 
351     /* works best if we force to linear type (endpoints match) */
352     lt->typeu = lt->typev = lt->typew = KEY_LINEAR;
353 
354     if (ltOb->runtime.curve_cache) {
355       /* prevent using deformed locations */
356       BKE_displist_free(&ltOb->runtime.curve_cache->disp);
357     }
358 
359     copy_m4_m4(mat, ltOb->obmat);
360     unit_m4(ltOb->obmat);
361     BKE_lattice_deform_coords(ltOb, NULL, vert_coords, uNew * vNew * wNew, 0, NULL, 1.0f);
362     copy_m4_m4(ltOb->obmat, mat);
363 
364     lt->typeu = typeu;
365     lt->typev = typev;
366     lt->typew = typew;
367   }
368 
369   lt->fu = fu;
370   lt->fv = fv;
371   lt->fw = fw;
372   lt->du = du;
373   lt->dv = dv;
374   lt->dw = dw;
375 
376   lt->pntsu = uNew;
377   lt->pntsv = vNew;
378   lt->pntsw = wNew;
379 
380   lt->actbp = LT_ACTBP_NONE;
381   MEM_freeN(lt->def);
382   lt->def = MEM_callocN(lt->pntsu * lt->pntsv * lt->pntsw * sizeof(BPoint), "lattice bp");
383 
384   bp = lt->def;
385 
386   for (i = 0; i < lt->pntsu * lt->pntsv * lt->pntsw; i++, bp++) {
387     copy_v3_v3(bp->vec, vert_coords[i]);
388   }
389 
390   MEM_freeN(vert_coords);
391 }
392 
BKE_lattice_add(Main * bmain,const char * name)393 Lattice *BKE_lattice_add(Main *bmain, const char *name)
394 {
395   Lattice *lt;
396 
397   lt = BKE_id_new(bmain, ID_LT, name);
398 
399   return lt;
400 }
401 
object_deform_mball(Object * ob,ListBase * dispbase)402 bool object_deform_mball(Object *ob, ListBase *dispbase)
403 {
404   if (ob->parent && ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
405     DispList *dl;
406 
407     for (dl = dispbase->first; dl; dl = dl->next) {
408       BKE_lattice_deform_coords(ob->parent, ob, (float(*)[3])dl->verts, dl->nr, 0, NULL, 1.0f);
409     }
410 
411     return true;
412   }
413 
414   return false;
415 }
416 
latt_bp(Lattice * lt,int u,int v,int w)417 static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
418 {
419   return &lt->def[BKE_lattice_index_from_uvw(lt, u, v, w)];
420 }
421 
outside_lattice(Lattice * lt)422 void outside_lattice(Lattice *lt)
423 {
424   BPoint *bp, *bp1, *bp2;
425   int u, v, w;
426   float fac1, du = 0.0, dv = 0.0, dw = 0.0;
427 
428   if (lt->flag & LT_OUTSIDE) {
429     bp = lt->def;
430 
431     if (lt->pntsu > 1) {
432       du = 1.0f / ((float)lt->pntsu - 1);
433     }
434     if (lt->pntsv > 1) {
435       dv = 1.0f / ((float)lt->pntsv - 1);
436     }
437     if (lt->pntsw > 1) {
438       dw = 1.0f / ((float)lt->pntsw - 1);
439     }
440 
441     for (w = 0; w < lt->pntsw; w++) {
442 
443       for (v = 0; v < lt->pntsv; v++) {
444 
445         for (u = 0; u < lt->pntsu; u++, bp++) {
446           if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 ||
447               w == lt->pntsw - 1) {
448             /* pass */
449           }
450           else {
451             bp->hide = 1;
452             bp->f1 &= ~SELECT;
453 
454             /* u extrema */
455             bp1 = latt_bp(lt, 0, v, w);
456             bp2 = latt_bp(lt, lt->pntsu - 1, v, w);
457 
458             fac1 = du * u;
459             bp->vec[0] = (1.0f - fac1) * bp1->vec[0] + fac1 * bp2->vec[0];
460             bp->vec[1] = (1.0f - fac1) * bp1->vec[1] + fac1 * bp2->vec[1];
461             bp->vec[2] = (1.0f - fac1) * bp1->vec[2] + fac1 * bp2->vec[2];
462 
463             /* v extrema */
464             bp1 = latt_bp(lt, u, 0, w);
465             bp2 = latt_bp(lt, u, lt->pntsv - 1, w);
466 
467             fac1 = dv * v;
468             bp->vec[0] += (1.0f - fac1) * bp1->vec[0] + fac1 * bp2->vec[0];
469             bp->vec[1] += (1.0f - fac1) * bp1->vec[1] + fac1 * bp2->vec[1];
470             bp->vec[2] += (1.0f - fac1) * bp1->vec[2] + fac1 * bp2->vec[2];
471 
472             /* w extrema */
473             bp1 = latt_bp(lt, u, v, 0);
474             bp2 = latt_bp(lt, u, v, lt->pntsw - 1);
475 
476             fac1 = dw * w;
477             bp->vec[0] += (1.0f - fac1) * bp1->vec[0] + fac1 * bp2->vec[0];
478             bp->vec[1] += (1.0f - fac1) * bp1->vec[1] + fac1 * bp2->vec[1];
479             bp->vec[2] += (1.0f - fac1) * bp1->vec[2] + fac1 * bp2->vec[2];
480 
481             mul_v3_fl(bp->vec, 1.0f / 3.0f);
482           }
483         }
484       }
485     }
486   }
487   else {
488     bp = lt->def;
489 
490     for (w = 0; w < lt->pntsw; w++) {
491       for (v = 0; v < lt->pntsv; v++) {
492         for (u = 0; u < lt->pntsu; u++, bp++) {
493           bp->hide = 0;
494         }
495       }
496     }
497   }
498 }
499 
BKE_lattice_vert_coords_get(const Lattice * lt,float (* vert_coords)[3])500 void BKE_lattice_vert_coords_get(const Lattice *lt, float (*vert_coords)[3])
501 {
502   const int vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
503   for (int i = 0; i < vert_len; i++) {
504     copy_v3_v3(vert_coords[i], lt->def[i].vec);
505   }
506 }
507 
BKE_lattice_vert_coords_alloc(const Lattice * lt,int * r_vert_len)508 float (*BKE_lattice_vert_coords_alloc(const Lattice *lt, int *r_vert_len))[3]
509 {
510   const int vert_len = *r_vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
511   float(*vert_coords)[3] = MEM_mallocN(sizeof(*vert_coords) * vert_len, __func__);
512   BKE_lattice_vert_coords_get(lt, vert_coords);
513   return vert_coords;
514 }
515 
BKE_lattice_vert_coords_apply_with_mat4(struct Lattice * lt,const float (* vert_coords)[3],const float mat[4][4])516 void BKE_lattice_vert_coords_apply_with_mat4(struct Lattice *lt,
517                                              const float (*vert_coords)[3],
518                                              const float mat[4][4])
519 {
520   int i, numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
521   for (i = 0; i < numVerts; i++) {
522     mul_v3_m4v3(lt->def[i].vec, mat, vert_coords[i]);
523   }
524 }
525 
BKE_lattice_vert_coords_apply(Lattice * lt,const float (* vert_coords)[3])526 void BKE_lattice_vert_coords_apply(Lattice *lt, const float (*vert_coords)[3])
527 {
528   const int vert_len = lt->pntsu * lt->pntsv * lt->pntsw;
529   for (int i = 0; i < vert_len; i++) {
530     copy_v3_v3(lt->def[i].vec, vert_coords[i]);
531   }
532 }
533 
BKE_lattice_modifiers_calc(struct Depsgraph * depsgraph,Scene * scene,Object * ob)534 void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
535 {
536   Lattice *lt = ob->data;
537   /* Get vertex coordinates from the original copy;
538    * otherwise we get already-modified coordinates. */
539   Object *ob_orig = DEG_get_original_object(ob);
540   VirtualModifierData virtualModifierData;
541   ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
542   float(*vert_coords)[3] = NULL;
543   int numVerts, editmode = (lt->editlatt != NULL);
544   const ModifierEvalContext mectx = {depsgraph, ob, 0};
545 
546   if (ob->runtime.curve_cache) {
547     BKE_displist_free(&ob->runtime.curve_cache->disp);
548   }
549   else {
550     ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice");
551   }
552 
553   for (; md; md = md->next) {
554     const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
555 
556     if (!(mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly)) {
557       continue;
558     }
559     if (!(md->mode & eModifierMode_Realtime)) {
560       continue;
561     }
562     if (editmode && !(md->mode & eModifierMode_Editmode)) {
563       continue;
564     }
565     if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
566       continue;
567     }
568     if (mti->type != eModifierTypeType_OnlyDeform) {
569       continue;
570     }
571 
572     if (!vert_coords) {
573       Lattice *lt_orig = ob_orig->data;
574       if (lt_orig->editlatt) {
575         lt_orig = lt_orig->editlatt->latt;
576       }
577       vert_coords = BKE_lattice_vert_coords_alloc(lt_orig, &numVerts);
578     }
579     mti->deformVerts(md, &mectx, NULL, vert_coords, numVerts);
580   }
581 
582   if (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) {
583     if (vert_coords) {
584       BKE_lattice_vert_coords_apply(ob->data, vert_coords);
585       MEM_freeN(vert_coords);
586     }
587   }
588   else {
589     /* Displist won't do anything; this is just for posterity's sake until we remove it. */
590     if (!vert_coords) {
591       Lattice *lt_orig = ob_orig->data;
592       if (lt_orig->editlatt) {
593         lt_orig = lt_orig->editlatt->latt;
594       }
595       vert_coords = BKE_lattice_vert_coords_alloc(lt_orig, &numVerts);
596     }
597 
598     DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
599     dl->type = DL_VERTS;
600     dl->parts = 1;
601     dl->nr = numVerts;
602     dl->verts = (float *)vert_coords;
603 
604     BLI_addtail(&ob->runtime.curve_cache->disp, dl);
605   }
606 }
607 
BKE_lattice_deform_verts_get(const struct Object * oblatt)608 struct MDeformVert *BKE_lattice_deform_verts_get(const struct Object *oblatt)
609 {
610   Lattice *lt = (Lattice *)oblatt->data;
611   BLI_assert(oblatt->type == OB_LATTICE);
612   if (lt->editlatt) {
613     lt = lt->editlatt->latt;
614   }
615   return lt->dvert;
616 }
617 
BKE_lattice_active_point_get(Lattice * lt)618 struct BPoint *BKE_lattice_active_point_get(Lattice *lt)
619 {
620   BLI_assert(GS(lt->id.name) == ID_LT);
621 
622   if (lt->editlatt) {
623     lt = lt->editlatt->latt;
624   }
625 
626   BLI_assert(lt->actbp < lt->pntsu * lt->pntsv * lt->pntsw);
627 
628   if ((lt->actbp != LT_ACTBP_NONE) && (lt->actbp < lt->pntsu * lt->pntsv * lt->pntsw)) {
629     return &lt->def[lt->actbp];
630   }
631 
632   return NULL;
633 }
634 
BKE_lattice_center_median(Lattice * lt,float cent[3])635 void BKE_lattice_center_median(Lattice *lt, float cent[3])
636 {
637   int i, numVerts;
638 
639   if (lt->editlatt) {
640     lt = lt->editlatt->latt;
641   }
642   numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
643 
644   zero_v3(cent);
645 
646   for (i = 0; i < numVerts; i++) {
647     add_v3_v3(cent, lt->def[i].vec);
648   }
649 
650   mul_v3_fl(cent, 1.0f / (float)numVerts);
651 }
652 
boundbox_lattice(Object * ob)653 static void boundbox_lattice(Object *ob)
654 {
655   BoundBox *bb;
656   Lattice *lt;
657   float min[3], max[3];
658 
659   if (ob->runtime.bb == NULL) {
660     ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "Lattice boundbox");
661   }
662 
663   bb = ob->runtime.bb;
664   lt = ob->data;
665 
666   INIT_MINMAX(min, max);
667   BKE_lattice_minmax_dl(ob, lt, min, max);
668   BKE_boundbox_init_from_minmax(bb, min, max);
669 
670   bb->flag &= ~BOUNDBOX_DIRTY;
671 }
672 
BKE_lattice_boundbox_get(Object * ob)673 BoundBox *BKE_lattice_boundbox_get(Object *ob)
674 {
675   boundbox_lattice(ob);
676 
677   return ob->runtime.bb;
678 }
679 
BKE_lattice_minmax_dl(Object * ob,Lattice * lt,float min[3],float max[3])680 void BKE_lattice_minmax_dl(Object *ob, Lattice *lt, float min[3], float max[3])
681 {
682   DispList *dl = ob->runtime.curve_cache ?
683                      BKE_displist_find(&ob->runtime.curve_cache->disp, DL_VERTS) :
684                      NULL;
685 
686   if (!dl) {
687     BKE_lattice_minmax(lt, min, max);
688   }
689   else {
690     int i, numVerts;
691 
692     if (lt->editlatt) {
693       lt = lt->editlatt->latt;
694     }
695     numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
696 
697     for (i = 0; i < numVerts; i++) {
698       minmax_v3v3_v3(min, max, &dl->verts[i * 3]);
699     }
700   }
701 }
702 
BKE_lattice_minmax(Lattice * lt,float min[3],float max[3])703 void BKE_lattice_minmax(Lattice *lt, float min[3], float max[3])
704 {
705   int i, numVerts;
706 
707   if (lt->editlatt) {
708     lt = lt->editlatt->latt;
709   }
710   numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
711 
712   for (i = 0; i < numVerts; i++) {
713     minmax_v3v3_v3(min, max, lt->def[i].vec);
714   }
715 }
716 
BKE_lattice_center_bounds(Lattice * lt,float cent[3])717 void BKE_lattice_center_bounds(Lattice *lt, float cent[3])
718 {
719   float min[3], max[3];
720 
721   INIT_MINMAX(min, max);
722 
723   BKE_lattice_minmax(lt, min, max);
724   mid_v3_v3v3(cent, min, max);
725 }
726 
BKE_lattice_transform(Lattice * lt,const float mat[4][4],bool do_keys)727 void BKE_lattice_transform(Lattice *lt, const float mat[4][4], bool do_keys)
728 {
729   BPoint *bp = lt->def;
730   int i = lt->pntsu * lt->pntsv * lt->pntsw;
731 
732   while (i--) {
733     mul_m4_v3(mat, bp->vec);
734     bp++;
735   }
736 
737   if (do_keys && lt->key) {
738     KeyBlock *kb;
739 
740     for (kb = lt->key->block.first; kb; kb = kb->next) {
741       float *fp = kb->data;
742       for (i = kb->totelem; i--; fp += 3) {
743         mul_m4_v3(mat, fp);
744       }
745     }
746   }
747 }
748 
BKE_lattice_translate(Lattice * lt,const float offset[3],bool do_keys)749 void BKE_lattice_translate(Lattice *lt, const float offset[3], bool do_keys)
750 {
751   int i, numVerts;
752 
753   numVerts = lt->pntsu * lt->pntsv * lt->pntsw;
754 
755   if (lt->def) {
756     for (i = 0; i < numVerts; i++) {
757       add_v3_v3(lt->def[i].vec, offset);
758     }
759   }
760 
761   if (lt->editlatt) {
762     for (i = 0; i < numVerts; i++) {
763       add_v3_v3(lt->editlatt->latt->def[i].vec, offset);
764     }
765   }
766 
767   if (do_keys && lt->key) {
768     KeyBlock *kb;
769 
770     for (kb = lt->key->block.first; kb; kb = kb->next) {
771       float *fp = kb->data;
772       for (i = kb->totelem; i--; fp += 3) {
773         add_v3_v3(fp, offset);
774       }
775     }
776   }
777 }
778 
BKE_lattice_is_any_selected(const Lattice * lt)779 bool BKE_lattice_is_any_selected(const Lattice *lt)
780 {
781   /* Intentionally don't handle 'lt->editlatt' (caller must do this). */
782   const BPoint *bp = lt->def;
783   int a = lt->pntsu * lt->pntsv * lt->pntsw;
784   while (a--) {
785     if (bp->hide == 0) {
786       if (bp->f1 & SELECT) {
787         return true;
788       }
789     }
790     bp++;
791   }
792   return false;
793 }
794 
795 /* **** Depsgraph evaluation **** */
796 
BKE_lattice_eval_geometry(struct Depsgraph * UNUSED (depsgraph),Lattice * UNUSED (latt))797 void BKE_lattice_eval_geometry(struct Depsgraph *UNUSED(depsgraph), Lattice *UNUSED(latt))
798 {
799 }
800 
801 /* Draw Engine */
802 void (*BKE_lattice_batch_cache_dirty_tag_cb)(Lattice *lt, int mode) = NULL;
803 void (*BKE_lattice_batch_cache_free_cb)(Lattice *lt) = NULL;
804 
BKE_lattice_batch_cache_dirty_tag(Lattice * lt,int mode)805 void BKE_lattice_batch_cache_dirty_tag(Lattice *lt, int mode)
806 {
807   if (lt->batch_cache) {
808     BKE_lattice_batch_cache_dirty_tag_cb(lt, mode);
809   }
810 }
BKE_lattice_batch_cache_free(Lattice * lt)811 void BKE_lattice_batch_cache_free(Lattice *lt)
812 {
813   if (lt->batch_cache) {
814     BKE_lattice_batch_cache_free_cb(lt);
815   }
816 }
817