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, <->id);
142 BKE_id_blend_write(writer, <->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, <->def);
160
161 BLO_read_data_address(reader, <->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, <->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, <->ipo); // XXX deprecated - old animation system
175 BLO_read_id_address(reader, lt->id.lib, <->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(<Ob->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 <->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 <->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