Blender V4.3
key.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cmath>
10#include <cstddef>
11#include <cstring>
12#include <optional>
13
14#include "MEM_guardedalloc.h"
15
16#include "BLI_blenlib.h"
17#include "BLI_endian_switch.h"
18#include "BLI_math_matrix.h"
19#include "BLI_math_vector.h"
20#include "BLI_string_utils.hh"
21#include "BLI_utildefines.h"
22
23#include "BLT_translation.hh"
24
25/* Allow using deprecated functionality for .blend file I/O. */
26#define DNA_DEPRECATED_ALLOW
27
28#include "BKE_attribute.hh"
29#include "DNA_ID.h"
30#include "DNA_anim_types.h"
31#include "DNA_key_types.h"
32#include "DNA_lattice_types.h"
33#include "DNA_mesh_types.h"
34#include "DNA_meshdata_types.h"
35#include "DNA_object_types.h"
36#include "DNA_scene_types.h"
37
38#include "BKE_anim_data.hh"
39#include "BKE_curve.hh"
40#include "BKE_customdata.hh"
41#include "BKE_deform.hh"
42#include "BKE_editmesh.hh"
43#include "BKE_idtype.hh"
44#include "BKE_key.hh"
45#include "BKE_lattice.hh"
46#include "BKE_lib_id.hh"
47#include "BKE_lib_query.hh"
48#include "BKE_main.hh"
49#include "BKE_mesh.hh"
50#include "BKE_scene.hh"
51
52#include "RNA_access.hh"
53#include "RNA_path.hh"
54#include "RNA_prototypes.hh"
55
56#include "BLO_read_write.hh"
57
58static void shapekey_copy_data(Main * /*bmain*/,
59 std::optional<Library *> /*owner_library*/,
60 ID *id_dst,
61 const ID *id_src,
62 const int /*flag*/)
63{
64 Key *key_dst = (Key *)id_dst;
65 const Key *key_src = (const Key *)id_src;
66 BLI_duplicatelist(&key_dst->block, &key_src->block);
67
68 KeyBlock *kb_dst, *kb_src;
69 for (kb_src = static_cast<KeyBlock *>(key_src->block.first),
70 kb_dst = static_cast<KeyBlock *>(key_dst->block.first);
71 kb_dst;
72 kb_src = kb_src->next, kb_dst = kb_dst->next)
73 {
74 if (kb_dst->data) {
75 kb_dst->data = MEM_dupallocN(kb_dst->data);
76 }
77 if (kb_src == key_src->refkey) {
78 key_dst->refkey = kb_dst;
79 }
80 }
81}
82
83static void shapekey_free_data(ID *id)
84{
85 Key *key = (Key *)id;
86 while (KeyBlock *kb = static_cast<KeyBlock *>(BLI_pophead(&key->block))) {
87 if (kb->data) {
88 MEM_freeN(kb->data);
89 }
90 MEM_freeN(kb);
91 }
92}
93
95{
96 Key *key = reinterpret_cast<Key *>(id);
98
100
103 }
104}
105
106static ID **shapekey_owner_pointer_get(ID *id, const bool debug_relationship_assert)
107{
108 Key *key = (Key *)id;
109
110 if (debug_relationship_assert) {
111 BLI_assert(key->from != nullptr);
112 BLI_assert(BKE_key_from_id(key->from) == key);
113 }
114
115 return &key->from;
116}
117
118static void shapekey_blend_write(BlendWriter *writer, ID *id, const void *id_address)
119{
120 Key *key = (Key *)id;
121 const bool is_undo = BLO_write_is_undo(writer);
122
123 /* write LibData */
124 BLO_write_id_struct(writer, Key, id_address, &key->id);
125 BKE_id_blend_write(writer, &key->id);
126
127 /* direct data */
128 LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
129 KeyBlock tmp_kb = *kb;
130 /* Do not store actual geometry data in case this is a library override ID. */
131 if (ID_IS_OVERRIDE_LIBRARY(key) && !is_undo) {
132 tmp_kb.totelem = 0;
133 tmp_kb.data = nullptr;
134 }
135 BLO_write_struct_at_address(writer, KeyBlock, kb, &tmp_kb);
136 if (tmp_kb.data != nullptr) {
137 BLO_write_raw(writer, tmp_kb.totelem * key->elemsize, tmp_kb.data);
138 }
139 }
140}
141
142/* old defines from DNA_ipo_types.h for data-type, stored in DNA - don't modify! */
143#define IPO_FLOAT 4
144#define IPO_BEZTRIPLE 100
145#define IPO_BPOINT 101
146
147static void switch_endian_keyblock(Key *key, KeyBlock *kb)
148{
149 int elemsize = key->elemsize;
150 char *data = static_cast<char *>(kb->data);
151
152 for (int a = 0; a < kb->totelem; a++) {
153 const char *cp = key->elemstr;
154 char *poin = data;
155
156 while (cp[0]) { /* cp[0] == amount */
157 switch (cp[1]) { /* cp[1] = type */
158 case IPO_FLOAT:
159 case IPO_BPOINT:
160 case IPO_BEZTRIPLE: {
161 int b = cp[0];
162 BLI_endian_switch_float_array((float *)poin, b);
163 poin += sizeof(float) * b;
164 break;
165 }
166 }
167
168 cp += 2;
169 }
170 data += elemsize;
171 }
172}
173
175{
176 Key *key = (Key *)id;
177 BLO_read_struct_list(reader, KeyBlock, &(key->block));
178
179 BLO_read_struct(reader, KeyBlock, &key->refkey);
180
181 LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
182 BLO_read_data_address(reader, &kb->data);
183
185 switch_endian_keyblock(key, kb);
186 }
187 }
188}
189
191{
192 /* ShapeKeys should always only be linked indirectly through their user ID (mesh, Curve etc.), or
193 * be fully local data. */
194 BLI_assert((id->tag & ID_TAG_EXTERN) == 0);
196}
197
199 /*id_code*/ ID_KE,
200 /*id_filter*/ FILTER_ID_KE,
201 /* Warning! key->from, could be more types in future? */
202 /*dependencies_id_types*/ FILTER_ID_ME | FILTER_ID_CU_LEGACY | FILTER_ID_LT,
203 /*main_listbase_index*/ INDEX_ID_KE,
204 /*struct_size*/ sizeof(Key),
205 /*name*/ "Key",
206 /*name_plural*/ N_("shape_keys"),
207 /*translation_context*/ BLT_I18NCONTEXT_ID_SHAPEKEY,
209 /*asset_type_info*/ nullptr,
210
211 /*init_data*/ nullptr,
212 /*copy_data*/ shapekey_copy_data,
213 /*free_data*/ shapekey_free_data,
214 /*make_local*/ nullptr,
215 /*foreach_id*/ shapekey_foreach_id,
216 /*foreach_cache*/ nullptr,
217 /*foreach_path*/ nullptr,
218 /* A bit weird, due to shape-keys not being strictly speaking embedded data... But they also
219 * share a lot with those (non linkable, only ever used by one owner ID, etc.). */
220 /*owner_pointer_get*/ shapekey_owner_pointer_get,
221
222 /*blend_write*/ shapekey_blend_write,
223 /*blend_read_data*/ shapekey_blend_read_data,
224 /*blend_read_after_liblink*/ shapekey_blend_read_after_liblink,
225
226 /*blend_read_undo_preserve*/ nullptr,
227
228 /*lib_override_apply_post*/ nullptr,
229};
230
231#define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */
232#define KEY_MODE_BPOINT 1
233#define KEY_MODE_BEZTRIPLE 2
234
235/* Internal use only. */
240
242{
243 shapekey_free_data(&key->id);
244}
245
247{
248 while (KeyBlock *kb = static_cast<KeyBlock *>(BLI_pophead(&key->block))) {
249 if (kb->data) {
250 MEM_freeN(kb->data);
251 }
252 MEM_freeN(kb);
253 }
254}
255
256Key *BKE_key_add(Main *bmain, ID *id) /* common function */
257{
258 Key *key;
259 char *el;
260
261 key = static_cast<Key *>(BKE_id_new(bmain, ID_KE, "Key"));
262
263 key->type = KEY_NORMAL;
264 key->from = id;
265
266 key->uidgen = 1;
267
268 /* XXX the code here uses some defines which will soon be deprecated... */
269 switch (GS(id->name)) {
270 case ID_ME:
271 el = key->elemstr;
272
274 el[1] = IPO_FLOAT;
275 el[2] = 0;
276
277 key->elemsize = sizeof(float[KEYELEM_FLOAT_LEN_COORD]);
278
279 break;
280 case ID_LT:
281 el = key->elemstr;
282
284 el[1] = IPO_FLOAT;
285 el[2] = 0;
286
287 key->elemsize = sizeof(float[KEYELEM_FLOAT_LEN_COORD]);
288
289 break;
290 case ID_CU_LEGACY:
291 el = key->elemstr;
292
294 el[1] = IPO_BPOINT;
295 el[2] = 0;
296
297 key->elemsize = sizeof(float[KEYELEM_ELEM_SIZE_CURVE]);
298
299 break;
300
301 default:
302 break;
303 }
304
305 return key;
306}
307
309{
310 KeyBlock *kb;
311
312 /* locate the key which is out of position */
313 for (kb = static_cast<KeyBlock *>(key->block.first); kb; kb = kb->next) {
314 if ((kb->next) && (kb->pos > kb->next->pos)) {
315 break;
316 }
317 }
318
319 /* if we find a key, move it */
320 if (kb) {
321 kb = kb->next; /* next key is the out-of-order one */
322 BLI_remlink(&key->block, kb);
323
324 /* find the right location and insert before */
325 LISTBASE_FOREACH (KeyBlock *, kb2, &key->block) {
326 if (kb2->pos > kb->pos) {
327 BLI_insertlinkafter(&key->block, kb2->prev, kb);
328 break;
329 }
330 }
331 }
332
333 /* new rule; first key is refkey, this to match drawing channels... */
334 key->refkey = static_cast<KeyBlock *>(key->block.first);
335}
336
337/**************** do the key ****************/
338
339void key_curve_position_weights(float t, float data[4], int type)
340{
341 float t2, t3, fc;
342
343 if (type == KEY_LINEAR) {
344 data[0] = 0.0f;
345 data[1] = -t + 1.0f;
346 data[2] = t;
347 data[3] = 0.0f;
348 }
349 else if (type == KEY_CARDINAL) {
350 t2 = t * t;
351 t3 = t2 * t;
352 fc = 0.71f;
353
354 data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
355 data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
356 data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
357 data[3] = fc * t3 - fc * t2;
358 }
359 else if (type == KEY_BSPLINE) {
360 t2 = t * t;
361 t3 = t2 * t;
362
363 data[0] = -0.16666666f * t3 + 0.5f * t2 - 0.5f * t + 0.16666666f;
364 data[1] = 0.5f * t3 - t2 + 0.66666666f;
365 data[2] = -0.5f * t3 + 0.5f * t2 + 0.5f * t + 0.16666666f;
366 data[3] = 0.16666666f * t3;
367 }
368 else if (type == KEY_CATMULL_ROM) {
369 t2 = t * t;
370 t3 = t2 * t;
371 fc = 0.5f;
372
373 data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
374 data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
375 data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
376 data[3] = fc * t3 - fc * t2;
377 }
378}
379
380void key_curve_tangent_weights(float t, float data[4], int type)
381{
382 float t2, fc;
383
384 if (type == KEY_LINEAR) {
385 data[0] = 0.0f;
386 data[1] = -1.0f;
387 data[2] = 1.0f;
388 data[3] = 0.0f;
389 }
390 else if (type == KEY_CARDINAL) {
391 t2 = t * t;
392 fc = 0.71f;
393
394 data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
395 data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
396 data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
397 data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
398 }
399 else if (type == KEY_BSPLINE) {
400 t2 = t * t;
401
402 data[0] = -0.5f * t2 + t - 0.5f;
403 data[1] = 1.5f * t2 - t * 2.0f;
404 data[2] = -1.5f * t2 + t + 0.5f;
405 data[3] = 0.5f * t2;
406 }
407 else if (type == KEY_CATMULL_ROM) {
408 t2 = t * t;
409 fc = 0.5f;
410
411 data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
412 data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
413 data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
414 data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
415 }
416}
417
418void key_curve_normal_weights(float t, float data[4], int type)
419{
420 float fc;
421
422 if (type == KEY_LINEAR) {
423 data[0] = 0.0f;
424 data[1] = 0.0f;
425 data[2] = 0.0f;
426 data[3] = 0.0f;
427 }
428 else if (type == KEY_CARDINAL) {
429 fc = 0.71f;
430
431 data[0] = -6.0f * fc * t + 4.0f * fc;
432 data[1] = 6.0f * (2.0f - fc) * t + 2.0f * (fc - 3.0f);
433 data[2] = 6.0f * (fc - 2.0f) * t + 2.0f * (3.0f - 2.0f * fc);
434 data[3] = 6.0f * fc * t - 2.0f * fc;
435 }
436 else if (type == KEY_BSPLINE) {
437 data[0] = -1.0f * t + 1.0f;
438 data[1] = 3.0f * t - 2.0f;
439 data[2] = -3.0f * t + 1.0f;
440 data[3] = 1.0f * t;
441 }
442 else if (type == KEY_CATMULL_ROM) {
443 fc = 0.5f;
444
445 data[0] = -6.0f * fc * t + 4.0f * fc;
446 data[1] = 6.0f * (2.0f - fc) * t + 2.0f * (fc - 3.0f);
447 data[2] = 6.0f * (fc - 2.0f) * t + 2.0f * (3.0f - 2.0f * fc);
448 data[3] = 6.0f * fc * t - 2.0f * fc;
449 }
450}
451
452static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
453{
454 /* return 1 means k[2] is the position, return 0 means interpolate */
455 KeyBlock *k1, *firstkey;
456 float d, dpos, ofs = 0, lastpos;
457 short bsplinetype;
458
459 firstkey = static_cast<KeyBlock *>(lb->first);
460 k1 = static_cast<KeyBlock *>(lb->last);
461 lastpos = k1->pos;
462 dpos = lastpos - firstkey->pos;
463
464 if (fac < firstkey->pos) {
465 fac = firstkey->pos;
466 }
467 else if (fac > k1->pos) {
468 fac = k1->pos;
469 }
470
471 k1 = k[0] = k[1] = k[2] = k[3] = firstkey;
472 t[0] = t[1] = t[2] = t[3] = k1->pos;
473
474#if 0
475 if (fac < 0.0 || fac > 1.0) {
476 return 1;
477 }
478#endif
479
480 if (k1->next == nullptr) {
481 return 1;
482 }
483
484 if (cycl) { /* pre-sort */
485 k[2] = k1->next;
486 k[3] = k[2]->next;
487 if (k[3] == nullptr) {
488 k[3] = k1;
489 }
490 while (k1) {
491 if (k1->next == nullptr) {
492 k[0] = k1;
493 }
494 k1 = k1->next;
495 }
496 // k1 = k[1]; /* UNUSED */
497 t[0] = k[0]->pos;
498 t[1] += dpos;
499 t[2] = k[2]->pos + dpos;
500 t[3] = k[3]->pos + dpos;
501 fac += dpos;
502 ofs = dpos;
503 if (k[3] == k[1]) {
504 t[3] += dpos;
505 ofs = 2.0f * dpos;
506 }
507 if (fac < t[1]) {
508 fac += dpos;
509 }
510 k1 = k[3];
511 }
512 else { /* pre-sort */
513 k[2] = k1->next;
514 t[2] = k[2]->pos;
515 k[3] = k[2]->next;
516 if (k[3] == nullptr) {
517 k[3] = k[2];
518 }
519 t[3] = k[3]->pos;
520 k1 = k[3];
521 }
522
523 while (t[2] < fac) { /* find correct location */
524 if (k1->next == nullptr) {
525 if (cycl) {
526 k1 = firstkey;
527 ofs += dpos;
528 }
529 else if (t[2] == t[3]) {
530 break;
531 }
532 }
533 else {
534 k1 = k1->next;
535 }
536
537 t[0] = t[1];
538 k[0] = k[1];
539 t[1] = t[2];
540 k[1] = k[2];
541 t[2] = t[3];
542 k[2] = k[3];
543 t[3] = k1->pos + ofs;
544 k[3] = k1;
545
546 if (ofs > 2.1f + lastpos) {
547 break;
548 }
549 }
550
551 bsplinetype = 0;
552 if (k[1]->type == KEY_BSPLINE || k[2]->type == KEY_BSPLINE) {
553 bsplinetype = 1;
554 }
555
556 if (cycl == 0) {
557 if (bsplinetype == 0) { /* B spline doesn't go through the control points */
558 if (fac <= t[1]) { /* fac for 1st key */
559 t[2] = t[1];
560 k[2] = k[1];
561 return 1;
562 }
563 if (fac >= t[2]) { /* fac after 2nd key */
564 return 1;
565 }
566 }
567 else if (fac > t[2]) { /* last key */
568 fac = t[2];
569 k[3] = k[2];
570 t[3] = t[2];
571 }
572 }
573
574 d = t[2] - t[1];
575 if (d == 0.0f) {
576 if (bsplinetype == 0) {
577 return 1; /* both keys equal */
578 }
579 }
580 else {
581 d = (fac - t[1]) / d;
582 }
583
584 /* interpolation */
585 key_curve_position_weights(d, t, k[1]->type);
586
587 if (k[1]->type != k[2]->type) {
588 float t_other[4];
589 key_curve_position_weights(d, t_other, k[2]->type);
590 interp_v4_v4v4(t, t, t_other, d);
591 }
592
593 return 0;
594}
595
596static void flerp(int tot,
597 float *in,
598 const float *f0,
599 const float *f1,
600 const float *f2,
601 const float *f3,
602 const float *t)
603{
604 int a;
605
606 for (a = 0; a < tot; a++) {
607 in[a] = t[0] * f0[a] + t[1] * f1[a] + t[2] * f2[a] + t[3] * f3[a];
608 }
609}
610
611static void rel_flerp(int tot, float *in, const float *ref, const float *out, float fac)
612{
613 int a;
614
615 for (a = 0; a < tot; a++) {
616 in[a] -= fac * (ref[a] - out[a]);
617 }
618}
619
620static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata)
621{
622 if (kb == actkb) {
623 /* this hack makes it possible to edit shape keys in
624 * edit mode with shape keys blending applied */
625 if (GS(key->from->name) == ID_ME) {
626 Mesh *mesh;
627 BMVert *eve;
628 BMIter iter;
629 float(*co)[3];
630 int a;
631
632 mesh = (Mesh *)key->from;
633
634 if (mesh->runtime->edit_mesh && mesh->runtime->edit_mesh->bm->totvert == kb->totelem) {
635 a = 0;
636 co = static_cast<float(*)[3]>(MEM_mallocN(
637 sizeof(float[3]) * mesh->runtime->edit_mesh->bm->totvert, "key_block_get_data"));
638
639 BM_ITER_MESH (eve, &iter, mesh->runtime->edit_mesh->bm, BM_VERTS_OF_MESH) {
640 copy_v3_v3(co[a], eve->co);
641 a++;
642 }
643
644 *freedata = (char *)co;
645 return (char *)co;
646 }
647 }
648 }
649
650 *freedata = nullptr;
651 return static_cast<char *>(kb->data);
652}
653
654/* currently only the first value of 'r_ofs' may be set. */
656 const Key *key, const int mode, int *r_poinsize, int *r_ofs, int *r_step)
657{
658 if (key->from == nullptr) {
659 return false;
660 }
661
662 *r_step = 1;
663
664 switch (GS(key->from->name)) {
665 case ID_ME:
666 *r_ofs = sizeof(float[KEYELEM_FLOAT_LEN_COORD]);
667 *r_poinsize = *r_ofs;
668 break;
669 case ID_LT:
670 *r_ofs = sizeof(float[KEYELEM_FLOAT_LEN_COORD]);
671 *r_poinsize = *r_ofs;
672 break;
673 case ID_CU_LEGACY:
674 if (mode == KEY_MODE_BPOINT) {
675 *r_ofs = sizeof(float[KEYELEM_FLOAT_LEN_BPOINT]);
676 *r_step = KEYELEM_ELEM_LEN_BPOINT;
677 }
678 else {
679 *r_ofs = sizeof(float[KEYELEM_FLOAT_LEN_BEZTRIPLE]);
681 }
682 *r_poinsize = sizeof(float[KEYELEM_ELEM_SIZE_CURVE]);
683 break;
684 default:
685 BLI_assert_msg(0, "invalid 'key->from' ID type");
686 return false;
687 }
688
689 return true;
690}
691
692static void cp_key(const int start,
693 int end,
694 const int tot,
695 char *poin,
696 Key *key,
697 KeyBlock *actkb,
698 KeyBlock *kb,
699 float *weights,
700 const int mode)
701{
702 float ktot = 0.0, kd = 0.0;
703 int elemsize, poinsize = 0, a, step, *ofsp, ofs[32], flagflo = 0;
704 char *k1, *kref, *freek1, *freekref;
705 char *cp, elemstr[8];
706
707 /* currently always 0, in future key_pointer_size may assign */
708 ofs[1] = 0;
709
710 if (!key_pointer_size(key, mode, &poinsize, &ofs[0], &step)) {
711 return;
712 }
713
714 if (end > tot) {
715 end = tot;
716 }
717
718 if (tot != kb->totelem) {
719 ktot = 0.0;
720 flagflo = 1;
721 if (kb->totelem) {
722 kd = kb->totelem / float(tot);
723 }
724 else {
725 return;
726 }
727 }
728
729 k1 = key_block_get_data(key, actkb, kb, &freek1);
730 kref = key_block_get_data(key, actkb, key->refkey, &freekref);
731
732 /* this exception is needed curves with multiple splines */
733 if (start != 0) {
734
735 poin += poinsize * start;
736
737 if (flagflo) {
738 ktot += start * kd;
739 a = int(floor(ktot));
740 if (a) {
741 ktot -= a;
742 k1 += a * key->elemsize;
743 }
744 }
745 else {
746 k1 += start * key->elemsize;
747 }
748 }
749
750 if (mode == KEY_MODE_BEZTRIPLE) {
751 elemstr[0] = 1;
752 elemstr[1] = IPO_BEZTRIPLE;
753 elemstr[2] = 0;
754 }
755
756 /* just do it here, not above! */
757 elemsize = key->elemsize * step;
758
759 for (a = start; a < end; a += step) {
760 cp = key->elemstr;
761 if (mode == KEY_MODE_BEZTRIPLE) {
762 cp = elemstr;
763 }
764
765 ofsp = ofs;
766
767 while (cp[0]) {
768
769 switch (cp[1]) {
770 case IPO_FLOAT:
771 if (weights) {
772 memcpy(poin, kref, sizeof(float[KEYELEM_FLOAT_LEN_COORD]));
773 if (*weights != 0.0f) {
774 rel_flerp(
775 KEYELEM_FLOAT_LEN_COORD, (float *)poin, (float *)kref, (float *)k1, *weights);
776 }
777 weights++;
778 }
779 else {
780 memcpy(poin, k1, sizeof(float[KEYELEM_FLOAT_LEN_COORD]));
781 }
782 break;
783 case IPO_BPOINT:
784 memcpy(poin, k1, sizeof(float[KEYELEM_FLOAT_LEN_BPOINT]));
785 break;
786 case IPO_BEZTRIPLE:
787 memcpy(poin, k1, sizeof(float[KEYELEM_FLOAT_LEN_BEZTRIPLE]));
788 break;
789 default:
790 /* should never happen */
791 if (freek1) {
792 MEM_freeN(freek1);
793 }
794 if (freekref) {
795 MEM_freeN(freekref);
796 }
797 BLI_assert_msg(0, "invalid 'cp[1]'");
798 return;
799 }
800
801 poin += *ofsp;
802 cp += 2;
803 ofsp++;
804 }
805
806 /* are we going to be nasty? */
807 if (flagflo) {
808 ktot += kd;
809 while (ktot >= 1.0f) {
810 ktot -= 1.0f;
811 k1 += elemsize;
812 kref += elemsize;
813 }
814 }
815 else {
816 k1 += elemsize;
817 kref += elemsize;
818 }
819 }
820
821 if (freek1) {
822 MEM_freeN(freek1);
823 }
824 if (freekref) {
825 MEM_freeN(freekref);
826 }
827}
828
829static void cp_cu_key(Curve *cu,
830 Key *key,
831 KeyBlock *actkb,
832 KeyBlock *kb,
833 const int start,
834 int end,
835 char *out,
836 const int tot)
837{
838 Nurb *nu;
839 int a, step, a1, a2;
840
841 for (a = 0, nu = static_cast<Nurb *>(cu->nurb.first); nu; nu = nu->next, a += step) {
842 if (nu->bp) {
843 step = KEYELEM_ELEM_LEN_BPOINT * nu->pntsu * nu->pntsv;
844
845 a1 = max_ii(a, start);
846 a2 = min_ii(a + step, end);
847
848 if (a1 < a2) {
849 cp_key(a1, a2, tot, out, key, actkb, kb, nullptr, KEY_MODE_BPOINT);
850 }
851 }
852 else if (nu->bezt) {
854
855 /* exception because keys prefer to work with complete blocks */
856 a1 = max_ii(a, start);
857 a2 = min_ii(a + step, end);
858
859 if (a1 < a2) {
860 cp_key(a1, a2, tot, out, key, actkb, kb, nullptr, KEY_MODE_BEZTRIPLE);
861 }
862 }
863 else {
864 step = 0;
865 }
866 }
867}
868
869static void key_evaluate_relative(const int start,
870 int end,
871 const int tot,
872 char *basispoin,
873 Key *key,
874 KeyBlock *actkb,
875 float **per_keyblock_weights,
876 const int mode)
877{
878 KeyBlock *kb;
879 int *ofsp, ofs[3], elemsize, b, step;
880 char *cp, *poin, *reffrom, *from, elemstr[8];
881 int poinsize, keyblock_index;
882
883 /* currently always 0, in future key_pointer_size may assign */
884 ofs[1] = 0;
885
886 if (!key_pointer_size(key, mode, &poinsize, &ofs[0], &step)) {
887 return;
888 }
889
890 if (end > tot) {
891 end = tot;
892 }
893
894 /* In case of Bezier-triple. */
895 elemstr[0] = 1; /* Number of IPO-floats. */
896 elemstr[1] = IPO_BEZTRIPLE;
897 elemstr[2] = 0;
898
899 /* just here, not above! */
900 elemsize = key->elemsize * step;
901
902 /* step 1 init */
903 cp_key(start, end, tot, basispoin, key, actkb, key->refkey, nullptr, mode);
904
905 /* step 2: do it */
906
907 for (kb = static_cast<KeyBlock *>(key->block.first), keyblock_index = 0; kb;
908 kb = kb->next, keyblock_index++)
909 {
910 if (kb != key->refkey) {
911 float icuval = kb->curval;
912
913 /* only with value, and no difference allowed */
914 if (!(kb->flag & KEYBLOCK_MUTE) && icuval != 0.0f && kb->totelem == tot) {
915 KeyBlock *refb;
916 float weight,
917 *weights = per_keyblock_weights ? per_keyblock_weights[keyblock_index] : nullptr;
918 char *freefrom = nullptr;
919
920 /* reference now can be any block */
921 refb = static_cast<KeyBlock *>(BLI_findlink(&key->block, kb->relative));
922 if (refb == nullptr) {
923 continue;
924 }
925
926 poin = basispoin;
927 from = key_block_get_data(key, actkb, kb, &freefrom);
928
929 /* For meshes, use the original values instead of the bmesh values to
930 * maintain a constant offset. */
931 reffrom = static_cast<char *>(refb->data);
932
933 poin += start * poinsize;
934 reffrom += key->elemsize * start; /* key elemsize yes! */
935 from += key->elemsize * start;
936
937 for (b = start; b < end; b += step) {
938
939 weight = weights ? (*weights * icuval) : icuval;
940
941 cp = key->elemstr;
942 if (mode == KEY_MODE_BEZTRIPLE) {
943 cp = elemstr;
944 }
945
946 ofsp = ofs;
947
948 while (cp[0]) { /* (cp[0] == amount) */
949
950 switch (cp[1]) {
951 case IPO_FLOAT:
953 (float *)poin,
954 (float *)reffrom,
955 (float *)from,
956 weight);
957 break;
958 case IPO_BPOINT:
960 (float *)poin,
961 (float *)reffrom,
962 (float *)from,
963 weight);
964 break;
965 case IPO_BEZTRIPLE:
967 (float *)poin,
968 (float *)reffrom,
969 (float *)from,
970 weight);
971 break;
972 default:
973 /* should never happen */
974 if (freefrom) {
975 MEM_freeN(freefrom);
976 }
977 BLI_assert_msg(0, "invalid 'cp[1]'");
978 return;
979 }
980
981 poin += *ofsp;
982
983 cp += 2;
984 ofsp++;
985 }
986
987 reffrom += elemsize;
988 from += elemsize;
989
990 if (weights) {
991 weights++;
992 }
993 }
994
995 if (freefrom) {
996 MEM_freeN(freefrom);
997 }
998 }
999 }
1000 }
1001}
1002
1003static void do_key(const int start,
1004 int end,
1005 const int tot,
1006 char *poin,
1007 Key *key,
1008 KeyBlock *actkb,
1009 KeyBlock **k,
1010 float *t,
1011 const int mode)
1012{
1013 float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0;
1014 float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0;
1015 int a, step, ofs[32], *ofsp;
1016 int flagdo = 15, flagflo = 0, elemsize, poinsize = 0;
1017 char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4;
1018 char *cp, elemstr[8];
1019
1020 /* currently always 0, in future key_pointer_size may assign */
1021 ofs[1] = 0;
1022
1023 if (!key_pointer_size(key, mode, &poinsize, &ofs[0], &step)) {
1024 return;
1025 }
1026
1027 if (end > tot) {
1028 end = tot;
1029 }
1030
1031 k1 = key_block_get_data(key, actkb, k[0], &freek1);
1032 k2 = key_block_get_data(key, actkb, k[1], &freek2);
1033 k3 = key_block_get_data(key, actkb, k[2], &freek3);
1034 k4 = key_block_get_data(key, actkb, k[3], &freek4);
1035
1036 /* Test for more or less points (per key!) */
1037 if (tot != k[0]->totelem) {
1038 k1tot = 0.0;
1039 flagflo |= 1;
1040 if (k[0]->totelem) {
1041 k1d = k[0]->totelem / float(tot);
1042 }
1043 else {
1044 flagdo -= 1;
1045 }
1046 }
1047 if (tot != k[1]->totelem) {
1048 k2tot = 0.0;
1049 flagflo |= 2;
1050 if (k[0]->totelem) {
1051 k2d = k[1]->totelem / float(tot);
1052 }
1053 else {
1054 flagdo -= 2;
1055 }
1056 }
1057 if (tot != k[2]->totelem) {
1058 k3tot = 0.0;
1059 flagflo |= 4;
1060 if (k[0]->totelem) {
1061 k3d = k[2]->totelem / float(tot);
1062 }
1063 else {
1064 flagdo -= 4;
1065 }
1066 }
1067 if (tot != k[3]->totelem) {
1068 k4tot = 0.0;
1069 flagflo |= 8;
1070 if (k[0]->totelem) {
1071 k4d = k[3]->totelem / float(tot);
1072 }
1073 else {
1074 flagdo -= 8;
1075 }
1076 }
1077
1078 /* this exception is needed for curves with multiple splines */
1079 if (start != 0) {
1080
1081 poin += poinsize * start;
1082
1083 if (flagdo & 1) {
1084 if (flagflo & 1) {
1085 k1tot += start * k1d;
1086 a = int(floor(k1tot));
1087 if (a) {
1088 k1tot -= a;
1089 k1 += a * key->elemsize;
1090 }
1091 }
1092 else {
1093 k1 += start * key->elemsize;
1094 }
1095 }
1096 if (flagdo & 2) {
1097 if (flagflo & 2) {
1098 k2tot += start * k2d;
1099 a = int(floor(k2tot));
1100 if (a) {
1101 k2tot -= a;
1102 k2 += a * key->elemsize;
1103 }
1104 }
1105 else {
1106 k2 += start * key->elemsize;
1107 }
1108 }
1109 if (flagdo & 4) {
1110 if (flagflo & 4) {
1111 k3tot += start * k3d;
1112 a = int(floor(k3tot));
1113 if (a) {
1114 k3tot -= a;
1115 k3 += a * key->elemsize;
1116 }
1117 }
1118 else {
1119 k3 += start * key->elemsize;
1120 }
1121 }
1122 if (flagdo & 8) {
1123 if (flagflo & 8) {
1124 k4tot += start * k4d;
1125 a = int(floor(k4tot));
1126 if (a) {
1127 k4tot -= a;
1128 k4 += a * key->elemsize;
1129 }
1130 }
1131 else {
1132 k4 += start * key->elemsize;
1133 }
1134 }
1135 }
1136
1137 /* In case of bezier-triples. */
1138 elemstr[0] = 1; /* Number of IPO-floats. */
1139 elemstr[1] = IPO_BEZTRIPLE;
1140 elemstr[2] = 0;
1141
1142 /* only here, not above! */
1143 elemsize = key->elemsize * step;
1144
1145 for (a = start; a < end; a += step) {
1146 cp = key->elemstr;
1147 if (mode == KEY_MODE_BEZTRIPLE) {
1148 cp = elemstr;
1149 }
1150
1151 ofsp = ofs;
1152
1153 while (cp[0]) { /* (cp[0] == amount) */
1154
1155 switch (cp[1]) {
1156 case IPO_FLOAT:
1158 (float *)poin,
1159 (float *)k1,
1160 (float *)k2,
1161 (float *)k3,
1162 (float *)k4,
1163 t);
1164 break;
1165 case IPO_BPOINT:
1167 (float *)poin,
1168 (float *)k1,
1169 (float *)k2,
1170 (float *)k3,
1171 (float *)k4,
1172 t);
1173 break;
1174 case IPO_BEZTRIPLE:
1176 (float *)poin,
1177 (float *)k1,
1178 (float *)k2,
1179 (float *)k3,
1180 (float *)k4,
1181 t);
1182 break;
1183 default:
1184 /* should never happen */
1185 if (freek1) {
1186 MEM_freeN(freek1);
1187 }
1188 if (freek2) {
1189 MEM_freeN(freek2);
1190 }
1191 if (freek3) {
1192 MEM_freeN(freek3);
1193 }
1194 if (freek4) {
1195 MEM_freeN(freek4);
1196 }
1197 BLI_assert_msg(0, "invalid 'cp[1]'");
1198 return;
1199 }
1200
1201 poin += *ofsp;
1202 cp += 2;
1203 ofsp++;
1204 }
1205 /* lets do it the difficult way: when keys have a different size */
1206 if (flagdo & 1) {
1207 if (flagflo & 1) {
1208 k1tot += k1d;
1209 while (k1tot >= 1.0f) {
1210 k1tot -= 1.0f;
1211 k1 += elemsize;
1212 }
1213 }
1214 else {
1215 k1 += elemsize;
1216 }
1217 }
1218 if (flagdo & 2) {
1219 if (flagflo & 2) {
1220 k2tot += k2d;
1221 while (k2tot >= 1.0f) {
1222 k2tot -= 1.0f;
1223 k2 += elemsize;
1224 }
1225 }
1226 else {
1227 k2 += elemsize;
1228 }
1229 }
1230 if (flagdo & 4) {
1231 if (flagflo & 4) {
1232 k3tot += k3d;
1233 while (k3tot >= 1.0f) {
1234 k3tot -= 1.0f;
1235 k3 += elemsize;
1236 }
1237 }
1238 else {
1239 k3 += elemsize;
1240 }
1241 }
1242 if (flagdo & 8) {
1243 if (flagflo & 8) {
1244 k4tot += k4d;
1245 while (k4tot >= 1.0f) {
1246 k4tot -= 1.0f;
1247 k4 += elemsize;
1248 }
1249 }
1250 else {
1251 k4 += elemsize;
1252 }
1253 }
1254 }
1255
1256 if (freek1) {
1257 MEM_freeN(freek1);
1258 }
1259 if (freek2) {
1260 MEM_freeN(freek2);
1261 }
1262 if (freek3) {
1263 MEM_freeN(freek3);
1264 }
1265 if (freek4) {
1266 MEM_freeN(freek4);
1267 }
1268}
1269
1270static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cache)
1271{
1272 const MDeformVert *dvert = nullptr;
1273 BMEditMesh *em = nullptr;
1274 BMIter iter;
1275 BMVert *eve;
1276 int totvert = 0, defgrp_index = 0;
1277
1278 /* no vgroup string set? */
1279 if (vgroup[0] == 0) {
1280 return nullptr;
1281 }
1282
1283 /* gather dvert and totvert */
1284 if (ob->type == OB_MESH) {
1285 Mesh *mesh = static_cast<Mesh *>(ob->data);
1286 dvert = mesh->deform_verts().data();
1287 totvert = mesh->verts_num;
1288
1289 if (mesh->runtime->edit_mesh && mesh->runtime->edit_mesh->bm->totvert == totvert) {
1290 em = mesh->runtime->edit_mesh.get();
1291 }
1292 }
1293 else if (ob->type == OB_LATTICE) {
1294 Lattice *lt = static_cast<Lattice *>(ob->data);
1295 dvert = lt->dvert;
1296 totvert = lt->pntsu * lt->pntsv * lt->pntsw;
1297 }
1298
1299 if (dvert == nullptr) {
1300 return nullptr;
1301 }
1302
1303 /* find the group (weak loop-in-loop) */
1304 defgrp_index = BKE_object_defgroup_name_index(ob, vgroup);
1305 if (defgrp_index != -1) {
1306 float *weights;
1307
1308 if (cache) {
1309 if (cache->defgroup_weights == nullptr) {
1310 int num_defgroup = BKE_object_defgroup_count(ob);
1311 cache->defgroup_weights = static_cast<float **>(MEM_callocN(
1312 sizeof(*cache->defgroup_weights) * num_defgroup, "cached defgroup weights"));
1313 cache->num_defgroup_weights = num_defgroup;
1314 }
1315
1316 if (cache->defgroup_weights[defgrp_index]) {
1317 return cache->defgroup_weights[defgrp_index];
1318 }
1319 }
1320
1321 weights = static_cast<float *>(MEM_mallocN(totvert * sizeof(float), "weights"));
1322
1323 if (em) {
1324 int i;
1325 const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
1326 BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
1327 dvert = static_cast<const MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
1328 weights[i] = BKE_defvert_find_weight(dvert, defgrp_index);
1329 }
1330 }
1331 else {
1332 for (int i = 0; i < totvert; i++, dvert++) {
1333 weights[i] = BKE_defvert_find_weight(dvert, defgrp_index);
1334 }
1335 }
1336
1337 if (cache) {
1338 cache->defgroup_weights[defgrp_index] = weights;
1339 }
1340
1341 return weights;
1342 }
1343 return nullptr;
1344}
1345
1347{
1348 KeyBlock *keyblock;
1349 float **per_keyblock_weights;
1350 int keyblock_index;
1351
1352 per_keyblock_weights = static_cast<float **>(
1353 MEM_mallocN(sizeof(*per_keyblock_weights) * key->totkey, "per keyblock weights"));
1354
1355 for (keyblock = static_cast<KeyBlock *>(key->block.first), keyblock_index = 0; keyblock;
1356 keyblock = keyblock->next, keyblock_index++)
1357 {
1358 per_keyblock_weights[keyblock_index] = get_weights_array(ob, keyblock->vgroup, cache);
1359 }
1360
1361 return per_keyblock_weights;
1362}
1363
1365 float **per_keyblock_weights,
1366 WeightsArrayCache *cache)
1367{
1368 int a;
1369
1370 if (cache) {
1371 if (cache->num_defgroup_weights) {
1372 for (a = 0; a < cache->num_defgroup_weights; a++) {
1373 if (cache->defgroup_weights[a]) {
1374 MEM_freeN(cache->defgroup_weights[a]);
1375 }
1376 }
1378 }
1379 cache->defgroup_weights = nullptr;
1380 }
1381 else {
1382 for (a = 0; a < key->totkey; a++) {
1383 if (per_keyblock_weights[a]) {
1384 MEM_freeN(per_keyblock_weights[a]);
1385 }
1386 }
1387 }
1388
1389 MEM_freeN(per_keyblock_weights);
1390}
1391
1392static void do_mesh_key(Object *ob, Key *key, char *out, const int tot)
1393{
1394 KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
1395 float t[4];
1396 int flag = 0;
1397
1398 if (key->type == KEY_RELATIVE) {
1399 WeightsArrayCache cache = {0, nullptr};
1400 float **per_keyblock_weights;
1401 per_keyblock_weights = keyblock_get_per_block_weights(ob, key, &cache);
1403 0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
1404 keyblock_free_per_block_weights(key, per_keyblock_weights, &cache);
1405 }
1406 else {
1407 const float ctime_scaled = key->ctime / 100.0f;
1408
1409 flag = setkeys(ctime_scaled, &key->block, k, t, 0);
1410
1411 if (flag == 0) {
1412 do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
1413 }
1414 else {
1415 cp_key(0, tot, tot, (char *)out, key, actkb, k[2], nullptr, KEY_MODE_DUMMY);
1416 }
1417 }
1418}
1419
1420static void do_cu_key(
1421 Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, const int tot)
1422{
1423 Nurb *nu;
1424 int a, step;
1425
1426 for (a = 0, nu = static_cast<Nurb *>(cu->nurb.first); nu; nu = nu->next, a += step) {
1427 if (nu->bp) {
1428 step = KEYELEM_ELEM_LEN_BPOINT * nu->pntsu * nu->pntsv;
1429 do_key(a, a + step, tot, out, key, actkb, k, t, KEY_MODE_BPOINT);
1430 }
1431 else if (nu->bezt) {
1432 step = KEYELEM_ELEM_LEN_BEZTRIPLE * nu->pntsu;
1433 do_key(a, a + step, tot, out, key, actkb, k, t, KEY_MODE_BEZTRIPLE);
1434 }
1435 else {
1436 step = 0;
1437 }
1438 }
1439}
1440
1441static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const int tot)
1442{
1443 Nurb *nu;
1444 int a, step;
1445
1446 for (a = 0, nu = static_cast<Nurb *>(cu->nurb.first); nu; nu = nu->next, a += step) {
1447 if (nu->bp) {
1448 step = KEYELEM_ELEM_LEN_BPOINT * nu->pntsu * nu->pntsv;
1449 key_evaluate_relative(a, a + step, tot, out, key, actkb, nullptr, KEY_MODE_BPOINT);
1450 }
1451 else if (nu->bezt) {
1452 step = KEYELEM_ELEM_LEN_BEZTRIPLE * nu->pntsu;
1453 key_evaluate_relative(a, a + step, tot, out, key, actkb, nullptr, KEY_MODE_BEZTRIPLE);
1454 }
1455 else {
1456 step = 0;
1457 }
1458 }
1459}
1460
1461static void do_curve_key(Object *ob, Key *key, char *out, const int tot)
1462{
1463 Curve *cu = static_cast<Curve *>(ob->data);
1464 KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
1465 float t[4];
1466 int flag = 0;
1467
1468 if (key->type == KEY_RELATIVE) {
1469 do_rel_cu_key(cu, cu->key, actkb, out, tot);
1470 }
1471 else {
1472 const float ctime_scaled = key->ctime / 100.0f;
1473
1474 flag = setkeys(ctime_scaled, &key->block, k, t, 0);
1475
1476 if (flag == 0) {
1477 do_cu_key(cu, key, actkb, k, t, out, tot);
1478 }
1479 else {
1480 cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot);
1481 }
1482 }
1483}
1484
1485static void do_latt_key(Object *ob, Key *key, char *out, const int tot)
1486{
1487 Lattice *lt = static_cast<Lattice *>(ob->data);
1488 KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
1489 float t[4];
1490 int flag;
1491
1492 if (key->type == KEY_RELATIVE) {
1493 float **per_keyblock_weights;
1494 per_keyblock_weights = keyblock_get_per_block_weights(ob, key, nullptr);
1496 0, tot, tot, (char *)out, key, actkb, per_keyblock_weights, KEY_MODE_DUMMY);
1497 keyblock_free_per_block_weights(key, per_keyblock_weights, nullptr);
1498 }
1499 else {
1500 const float ctime_scaled = key->ctime / 100.0f;
1501
1502 flag = setkeys(ctime_scaled, &key->block, k, t, 0);
1503
1504 if (flag == 0) {
1505 do_key(0, tot, tot, (char *)out, key, actkb, k, t, KEY_MODE_DUMMY);
1506 }
1507 else {
1508 cp_key(0, tot, tot, (char *)out, key, actkb, k[2], nullptr, KEY_MODE_DUMMY);
1509 }
1510 }
1511
1512 if (lt->flag & LT_OUTSIDE) {
1513 outside_lattice(lt);
1514 }
1515}
1516
1517static void keyblock_data_convert_to_lattice(const float (*fp)[3],
1518 BPoint *bpoint,
1519 const int totpoint);
1520static void keyblock_data_convert_to_curve(const float *fp, ListBase *nurb, const int totpoint);
1521
1523 Object *ob, int *r_totelem, float *arr, size_t arr_size, ID *obdata)
1524{
1525 Key *key = BKE_key_from_object(ob);
1527 char *out;
1528 int tot = 0, size = 0;
1529
1530 if (key == nullptr || BLI_listbase_is_empty(&key->block)) {
1531 return nullptr;
1532 }
1533
1534 /* compute size of output array */
1535 if (ob->type == OB_MESH) {
1536 Mesh *mesh = static_cast<Mesh *>(ob->data);
1537
1538 tot = mesh->verts_num;
1539 size = tot * sizeof(float[KEYELEM_FLOAT_LEN_COORD]);
1540 }
1541 else if (ob->type == OB_LATTICE) {
1542 Lattice *lt = static_cast<Lattice *>(ob->data);
1543
1544 tot = lt->pntsu * lt->pntsv * lt->pntsw;
1545 size = tot * sizeof(float[KEYELEM_FLOAT_LEN_COORD]);
1546 }
1547 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
1548 Curve *cu = static_cast<Curve *>(ob->data);
1549
1551 size = tot * sizeof(float[KEYELEM_ELEM_SIZE_CURVE]);
1552 }
1553
1554 /* if nothing to interpolate, cancel */
1555 if (tot == 0 || size == 0) {
1556 return nullptr;
1557 }
1558
1559 /* allocate array */
1560 if (arr == nullptr) {
1561 out = static_cast<char *>(MEM_callocN(size, "BKE_key_evaluate_object out"));
1562 }
1563 else {
1564 if (arr_size != size) {
1565 return nullptr;
1566 }
1567
1568 out = (char *)arr;
1569 }
1570
1571 if (ob->shapeflag & OB_SHAPE_LOCK) {
1572 /* shape locked, copy the locked shape instead of blending */
1573 KeyBlock *kb = static_cast<KeyBlock *>(BLI_findlink(&key->block, ob->shapenr - 1));
1574
1575 if (kb && (kb->flag & KEYBLOCK_MUTE)) {
1576 kb = key->refkey;
1577 }
1578
1579 if (kb == nullptr) {
1580 kb = static_cast<KeyBlock *>(key->block.first);
1581 ob->shapenr = 1;
1582 }
1583
1584 if (OB_TYPE_SUPPORT_VGROUP(ob->type)) {
1585 float *weights = get_weights_array(ob, kb->vgroup, nullptr);
1586
1587 cp_key(0, tot, tot, out, key, actkb, kb, weights, 0);
1588
1589 if (weights) {
1590 MEM_freeN(weights);
1591 }
1592 }
1593 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
1594 cp_cu_key(static_cast<Curve *>(ob->data), key, actkb, kb, 0, tot, out, tot);
1595 }
1596 }
1597 else {
1598 if (ob->type == OB_MESH) {
1599 do_mesh_key(ob, key, out, tot);
1600 }
1601 else if (ob->type == OB_LATTICE) {
1602 do_latt_key(ob, key, out, tot);
1603 }
1604 else if (ob->type == OB_CURVES_LEGACY) {
1605 do_curve_key(ob, key, out, tot);
1606 }
1607 else if (ob->type == OB_SURF) {
1608 do_curve_key(ob, key, out, tot);
1609 }
1610 }
1611
1612 if (obdata != nullptr) {
1613 switch (GS(obdata->name)) {
1614 case ID_ME: {
1615 Mesh *mesh = (Mesh *)obdata;
1616 const int totvert = min_ii(tot, mesh->verts_num);
1617 mesh->vert_positions_for_write().take_front(totvert).copy_from(
1618 {reinterpret_cast<const blender::float3 *>(out), totvert});
1619 mesh->tag_positions_changed();
1620 break;
1621 }
1622 case ID_LT: {
1623 Lattice *lattice = (Lattice *)obdata;
1624 const int totpoint = min_ii(tot, lattice->pntsu * lattice->pntsv * lattice->pntsw);
1625 keyblock_data_convert_to_lattice((const float(*)[3])out, lattice->def, totpoint);
1626 break;
1627 }
1628 case ID_CU_LEGACY: {
1629 Curve *curve = (Curve *)obdata;
1630 const int totpoint = min_ii(tot, BKE_keyblock_curve_element_count(&curve->nurb));
1631 keyblock_data_convert_to_curve((const float *)out, &curve->nurb, totpoint);
1632 break;
1633 }
1634 default:
1636 }
1637 }
1638
1639 if (r_totelem) {
1640 *r_totelem = tot;
1641 }
1642 return (float *)out;
1643}
1644
1645float *BKE_key_evaluate_object(Object *ob, int *r_totelem)
1646{
1647 return BKE_key_evaluate_object_ex(ob, r_totelem, nullptr, 0, nullptr);
1648}
1649
1650int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index)
1651{
1652 int result = 0;
1653 int index = 0;
1654 for (const KeyBlock *kb = static_cast<const KeyBlock *>(key->block.first); kb;
1655 kb = kb->next, index++)
1656 {
1657 if (ELEM(shape_index, -1, index)) {
1658 result += kb->totelem;
1659 }
1660 }
1661 return result;
1662}
1663
1665{
1667}
1668
1669size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, const int shape_index)
1670{
1671 return size_t(BKE_keyblock_element_count_from_shape(key, shape_index)) * key->elemsize;
1672}
1673
1675{
1677}
1678
1679/* -------------------------------------------------------------------- */
1686void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int shape_index)
1687{
1688 uint8_t *elements = (uint8_t *)arr;
1689 int index = 0;
1690 for (const KeyBlock *kb = static_cast<const KeyBlock *>(key->block.first); kb;
1691 kb = kb->next, index++)
1692 {
1693 if (ELEM(shape_index, -1, index)) {
1694 const int block_elem_len = kb->totelem * key->elemsize;
1695 memcpy(elements, kb->data, block_elem_len);
1696 elements += block_elem_len;
1697 }
1698 }
1699}
1700
1701void BKE_keyblock_data_get(const Key *key, float (*arr)[3])
1702{
1704}
1705
1707 const int shape_index,
1708 const float (*coords)[3],
1709 const float mat[4][4])
1710{
1711 if (key->elemsize != sizeof(float[3])) {
1712 BLI_assert_msg(0, "Invalid elemsize");
1713 return;
1714 }
1715
1716 const float(*elements)[3] = coords;
1717
1718 int index = 0;
1719 for (KeyBlock *kb = static_cast<KeyBlock *>(key->block.first); kb; kb = kb->next, index++) {
1720 if (ELEM(shape_index, -1, index)) {
1721 const int block_elem_len = kb->totelem;
1722 float(*block_data)[3] = (float(*)[3])kb->data;
1723 for (int data_offset = 0; data_offset < block_elem_len; ++data_offset) {
1724 const float *src_data = (const float *)(elements + data_offset);
1725 float *dst_data = (float *)(block_data + data_offset);
1726 mul_v3_m4v3(dst_data, mat, src_data);
1727 }
1728 elements += block_elem_len;
1729 }
1730 }
1731}
1732
1734 Key *key, const ListBase *nurb, const int shape_index, const void *data, const float mat[4][4])
1735{
1736 const uint8_t *elements = static_cast<const uint8_t *>(data);
1737
1738 int index = 0;
1739 for (KeyBlock *kb = static_cast<KeyBlock *>(key->block.first); kb; kb = kb->next, index++) {
1740 if (ELEM(shape_index, -1, index)) {
1741 const int block_elem_size = kb->totelem * key->elemsize;
1742 BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data);
1743 elements += block_elem_size;
1744 }
1745 }
1746}
1747
1748void BKE_keyblock_data_set(Key *key, const int shape_index, const void *data)
1749{
1750 const uint8_t *elements = static_cast<const uint8_t *>(data);
1751 int index = 0;
1752 for (KeyBlock *kb = static_cast<KeyBlock *>(key->block.first); kb; kb = kb->next, index++) {
1753 if (ELEM(shape_index, -1, index)) {
1754 const int block_elem_size = kb->totelem * key->elemsize;
1755 memcpy(kb->data, elements, block_elem_size);
1756 elements += block_elem_size;
1757 }
1758 }
1759}
1760
1763bool BKE_key_idtype_support(const short id_type)
1764{
1765 switch (id_type) {
1766 case ID_ME:
1767 case ID_CU_LEGACY:
1768 case ID_LT:
1769 return true;
1770 default:
1771 return false;
1772 }
1773}
1774
1776{
1777 switch (GS(id->name)) {
1778 case ID_ME: {
1779 Mesh *mesh = (Mesh *)id;
1780 return &mesh->key;
1781 }
1782 case ID_CU_LEGACY: {
1783 Curve *cu = (Curve *)id;
1784 if (cu->vfont == nullptr) {
1785 return &cu->key;
1786 }
1787 break;
1788 }
1789 case ID_LT: {
1790 Lattice *lt = (Lattice *)id;
1791 return &lt->key;
1792 }
1793 default:
1794 break;
1795 }
1796
1797 return nullptr;
1798}
1799
1801{
1802 Key **key_p;
1803 key_p = BKE_key_from_id_p(id);
1804 if (key_p) {
1805 return *key_p;
1806 }
1807
1808 return nullptr;
1809}
1810
1812{
1813 if (ob == nullptr || ob->data == nullptr) {
1814 return nullptr;
1815 }
1816
1817 return BKE_key_from_id_p(static_cast<ID *>(ob->data));
1818}
1819
1821{
1822 Key **key_p;
1823 key_p = BKE_key_from_object_p(ob);
1824 if (key_p) {
1825 return *key_p;
1826 }
1827
1828 return nullptr;
1829}
1830
1831KeyBlock *BKE_keyblock_add(Key *key, const char *name)
1832{
1833 KeyBlock *kb;
1834 float curpos = -0.1;
1835 int tot;
1836
1837 kb = static_cast<KeyBlock *>(key->block.last);
1838 if (kb) {
1839 curpos = kb->pos;
1840 }
1841
1842 kb = MEM_cnew<KeyBlock>("Keyblock");
1843 BLI_addtail(&key->block, kb);
1844 kb->type = KEY_LINEAR;
1845
1846 tot = BLI_listbase_count(&key->block);
1847 if (name) {
1848 STRNCPY(kb->name, name);
1849 }
1850 else {
1851 if (tot == 1) {
1852 STRNCPY_UTF8(kb->name, DATA_("Basis"));
1853 }
1854 else {
1855 SNPRINTF(kb->name, DATA_("Key %d"), tot - 1);
1856 }
1857 }
1858
1859 BLI_uniquename(&key->block, kb, DATA_("Key"), '.', offsetof(KeyBlock, name), sizeof(kb->name));
1860
1861 kb->uid = key->uidgen++;
1862
1863 key->totkey++;
1864 if (key->totkey == 1) {
1865 key->refkey = kb;
1866 }
1867
1868 kb->slidermin = 0.0f;
1869 kb->slidermax = 1.0f;
1870
1871 /* \note caller may want to set this to current time, but don't do it here since we need to sort
1872 * which could cause problems in some cases, see #BKE_keyblock_add_ctime. */
1873 kb->pos = curpos + 0.1f; /* only used for absolute shape keys */
1874
1875 return kb;
1876}
1877
1878KeyBlock *BKE_keyblock_add_ctime(Key *key, const char *name, const bool do_force)
1879{
1880 KeyBlock *kb = BKE_keyblock_add(key, name);
1881 const float cpos = key->ctime / 100.0f;
1882
1883 /* In case of absolute keys, there is no point in adding more than one key with the same pos.
1884 * Hence only set new key-block pos to current time if none previous one already use it.
1885 * Now at least people just adding absolute keys without touching to ctime
1886 * won't have to systematically use retiming func (and have ordering issues, too). See #39897.
1887 */
1888 if (!do_force && (key->type != KEY_RELATIVE)) {
1889 LISTBASE_FOREACH (KeyBlock *, it_kb, &key->block) {
1890 /* Use epsilon to avoid floating point precision issues.
1891 * 1e-3 because the position is stored as frame * 1e-2. */
1892 if (compare_ff(it_kb->pos, cpos, 1e-3f)) {
1893 return kb;
1894 }
1895 }
1896 }
1897 if (do_force || (key->type != KEY_RELATIVE)) {
1898 kb->pos = cpos;
1899 BKE_key_sort(key);
1900 }
1901
1902 return kb;
1903}
1904
1906{
1907 Key *key = BKE_key_from_object(ob);
1908
1909 return BKE_keyblock_find_by_index(key, ob->shapenr - 1);
1910}
1911
1913{
1914 Key *key = BKE_key_from_object(ob);
1915
1916 if (key) {
1917 return key->refkey;
1918 }
1919
1920 return nullptr;
1921}
1922
1924{
1925 if (!key) {
1926 return nullptr;
1927 }
1928
1929 return static_cast<KeyBlock *>(BLI_findlink(&key->block, index));
1930}
1931
1932KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
1933{
1934 return static_cast<KeyBlock *>(BLI_findstring(&key->block, name, offsetof(KeyBlock, name)));
1935}
1936
1938{
1939 LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
1940 if (kb->uid == uid) {
1941 return kb;
1942 }
1943 }
1944 return nullptr;
1945}
1946
1948{
1949 kb_dst->pos = kb_src->pos;
1950 kb_dst->curval = kb_src->curval;
1951 kb_dst->type = kb_src->type;
1952 kb_dst->relative = kb_src->relative;
1953 STRNCPY(kb_dst->vgroup, kb_src->vgroup);
1954 kb_dst->slidermin = kb_src->slidermin;
1955 kb_dst->slidermax = kb_src->slidermax;
1956}
1957
1958std::optional<std::string> BKE_keyblock_curval_rnapath_get(const Key *key, const KeyBlock *kb)
1959{
1960 if (ELEM(nullptr, key, kb)) {
1961 return nullptr;
1962 }
1963 PointerRNA ptr = RNA_pointer_create((ID *)&key->id, &RNA_ShapeKey, (KeyBlock *)kb);
1964 PropertyRNA *prop = RNA_struct_find_property(&ptr, "value");
1965 return RNA_path_from_ID_to_property(&ptr, prop);
1966}
1967
1968/* conversion functions */
1969
1970/************************* Lattice ************************/
1971
1973{
1974 BPoint *bp;
1975 float(*fp)[3];
1976 int a, tot;
1977
1978 BLI_assert(kb->totelem == lt->pntsu * lt->pntsv * lt->pntsw);
1979
1980 tot = kb->totelem;
1981 if (tot == 0) {
1982 return;
1983 }
1984
1985 bp = lt->def;
1986 fp = static_cast<float(*)[3]>(kb->data);
1987 for (a = 0; a < kb->totelem; a++, fp++, bp++) {
1988 copy_v3_v3(*fp, bp->vec);
1989 }
1990}
1991
1993{
1994 int tot;
1995
1996 tot = lt->pntsu * lt->pntsv * lt->pntsw;
1997 if (tot == 0) {
1998 return;
1999 }
2000
2001 MEM_SAFE_FREE(kb->data);
2002
2003 kb->data = MEM_mallocN(lt->key->elemsize * tot, __func__);
2004 kb->totelem = tot;
2005
2007}
2008
2009static void keyblock_data_convert_to_lattice(const float (*fp)[3],
2010 BPoint *bpoint,
2011 const int totpoint)
2012{
2013 for (int i = 0; i < totpoint; i++, fp++, bpoint++) {
2014 copy_v3_v3(bpoint->vec, *fp);
2015 }
2016}
2017
2019{
2020 BPoint *bp = lt->def;
2021 const float(*fp)[3] = static_cast<const float(*)[3]>(kb->data);
2022 const int tot = min_ii(kb->totelem, lt->pntsu * lt->pntsv * lt->pntsw);
2023
2025}
2026
2027/************************* Curve ************************/
2028
2030{
2031 const Nurb *nu;
2032 int tot = 0;
2033
2034 nu = static_cast<const Nurb *>(nurb->first);
2035 while (nu) {
2036 if (nu->bezt) {
2037 tot += KEYELEM_ELEM_LEN_BEZTRIPLE * nu->pntsu;
2038 }
2039 else if (nu->bp) {
2040 tot += KEYELEM_ELEM_LEN_BPOINT * nu->pntsu * nu->pntsv;
2041 }
2042
2043 nu = nu->next;
2044 }
2045 return tot;
2046}
2047
2048void BKE_keyblock_update_from_curve(const Curve * /*cu*/, KeyBlock *kb, const ListBase *nurb)
2049{
2050 BezTriple *bezt;
2051 BPoint *bp;
2052 float *fp;
2053 int a, tot;
2054
2055 /* count */
2057
2058 tot = kb->totelem;
2059 if (tot == 0) {
2060 return;
2061 }
2062
2063 fp = static_cast<float *>(kb->data);
2064 LISTBASE_FOREACH (Nurb *, nu, nurb) {
2065 if (nu->bezt) {
2066 for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
2067 for (int i = 0; i < 3; i++) {
2068 copy_v3_v3(&fp[i * 3], bezt->vec[i]);
2069 }
2070 fp[9] = bezt->tilt;
2071 fp[10] = bezt->radius;
2073 }
2074 }
2075 else {
2076 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++) {
2077 copy_v3_v3(fp, bp->vec);
2078 fp[3] = bp->tilt;
2079 fp[4] = bp->radius;
2081 }
2082 }
2083 }
2084}
2085
2087 const float mat[4][4],
2088 const void *src_data,
2089 void *dst_data)
2090{
2091 const float *src = static_cast<const float *>(src_data);
2092 float *dst = static_cast<float *>(dst_data);
2093 LISTBASE_FOREACH (Nurb *, nu, nurb) {
2094 if (nu->bezt) {
2095 for (int a = nu->pntsu; a; a--) {
2096 for (int i = 0; i < 3; i++) {
2097 mul_v3_m4v3(&dst[i * 3], mat, &src[i * 3]);
2098 }
2099 dst[9] = src[9];
2100 dst[10] = src[10];
2103 }
2104 }
2105 else {
2106 for (int a = nu->pntsu * nu->pntsv; a; a--) {
2107 mul_v3_m4v3(dst, mat, src);
2108 dst[3] = src[3];
2109 dst[4] = src[4];
2112 }
2113 }
2114 }
2115}
2116
2118{
2119 int tot;
2120
2121 /* count */
2123 if (tot == 0) {
2124 return;
2125 }
2126
2127 MEM_SAFE_FREE(kb->data);
2128
2129 kb->data = MEM_mallocN(cu->key->elemsize * tot, __func__);
2130 kb->totelem = tot;
2131
2132 BKE_keyblock_update_from_curve(cu, kb, nurb);
2133}
2134
2135static void keyblock_data_convert_to_curve(const float *fp, ListBase *nurb, int totpoint)
2136{
2137 for (Nurb *nu = static_cast<Nurb *>(nurb->first); nu && totpoint > 0; nu = nu->next) {
2138 if (nu->bezt != nullptr) {
2139 BezTriple *bezt = nu->bezt;
2140 for (int i = nu->pntsu; i && (totpoint -= KEYELEM_ELEM_LEN_BEZTRIPLE) >= 0;
2141 i--, bezt++, fp += KEYELEM_FLOAT_LEN_BEZTRIPLE)
2142 {
2143 for (int j = 0; j < 3; j++) {
2144 copy_v3_v3(bezt->vec[j], &fp[j * 3]);
2145 }
2146 bezt->tilt = fp[9];
2147 bezt->radius = fp[10];
2148 }
2149 }
2150 else {
2151 BPoint *bp = nu->bp;
2152 for (int i = nu->pntsu * nu->pntsv; i && (totpoint -= KEYELEM_ELEM_LEN_BPOINT) >= 0;
2153 i--, bp++, fp += KEYELEM_FLOAT_LEN_BPOINT)
2154 {
2155 copy_v3_v3(bp->vec, fp);
2156 bp->tilt = fp[3];
2157 bp->radius = fp[4];
2158 }
2159 }
2160 }
2161}
2162
2164{
2165 const float *fp = static_cast<const float *>(kb->data);
2166 const int tot = min_ii(kb->totelem, BKE_keyblock_curve_element_count(nurb));
2167
2168 keyblock_data_convert_to_curve(fp, nurb, tot);
2169}
2170
2171/************************* Mesh ************************/
2172
2174{
2175 BLI_assert(mesh->verts_num == kb->totelem);
2176
2177 const int tot = mesh->verts_num;
2178 if (tot == 0) {
2179 return;
2180 }
2181
2182 const blender::Span<blender::float3> positions = mesh->vert_positions();
2183 memcpy(kb->data, positions.data(), sizeof(float[3]) * tot);
2184}
2185
2186void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
2187{
2188 const int len = mesh->verts_num;
2189
2190 if (mesh->verts_num == 0) {
2191 return;
2192 }
2193
2194 MEM_SAFE_FREE(kb->data);
2195
2196 kb->data = MEM_malloc_arrayN(size_t(len), size_t(key->elemsize), __func__);
2197 kb->totelem = len;
2198
2200}
2201
2203 float (*vert_positions)[3],
2204 const int totvert)
2205{
2206 const int tot = min_ii(kb->totelem, totvert);
2207 memcpy(vert_positions, kb->data, sizeof(float[3]) * tot);
2208}
2209
2211 Mesh *mesh,
2212 float (*r_vert_normals)[3],
2213 float (*r_face_normals)[3],
2214 float (*r_loop_normals)[3])
2215{
2216 using namespace blender;
2217 using namespace blender::bke;
2218 if (r_vert_normals == nullptr && r_face_normals == nullptr && r_loop_normals == nullptr) {
2219 return;
2220 }
2221
2222 blender::Array<blender::float3> positions(mesh->vert_positions());
2224 kb, reinterpret_cast<float(*)[3]>(positions.data()), mesh->verts_num);
2225 const blender::Span<blender::int2> edges = mesh->edges();
2226 const blender::OffsetIndices faces = mesh->faces();
2227 const blender::Span<int> corner_verts = mesh->corner_verts();
2228 const blender::Span<int> corner_edges = mesh->corner_edges();
2229
2230 const bool loop_normals_needed = r_loop_normals != nullptr;
2231 const bool vert_normals_needed = r_vert_normals != nullptr || loop_normals_needed;
2232 const bool face_normals_needed = r_face_normals != nullptr || vert_normals_needed ||
2233 loop_normals_needed;
2234
2235 float(*vert_normals)[3] = r_vert_normals;
2236 float(*face_normals)[3] = r_face_normals;
2237 bool free_vert_normals = false;
2238 bool free_face_normals = false;
2239 if (vert_normals_needed && r_vert_normals == nullptr) {
2240 vert_normals = static_cast<float(*)[3]>(
2241 MEM_malloc_arrayN(mesh->verts_num, sizeof(float[3]), __func__));
2242 free_vert_normals = true;
2243 }
2244 if (face_normals_needed && r_face_normals == nullptr) {
2245 face_normals = static_cast<float(*)[3]>(
2246 MEM_malloc_arrayN(mesh->faces_num, sizeof(float[3]), __func__));
2247 free_face_normals = true;
2248 }
2249
2250 if (face_normals_needed) {
2251 mesh::normals_calc_faces(positions,
2252 faces,
2253 corner_verts,
2254 {reinterpret_cast<blender::float3 *>(face_normals), faces.size()});
2255 }
2256 if (vert_normals_needed) {
2257 mesh::normals_calc_verts(
2258 positions,
2259 faces,
2260 corner_verts,
2261 mesh->vert_to_face_map(),
2262 {reinterpret_cast<const blender::float3 *>(face_normals), faces.size()},
2263 {reinterpret_cast<blender::float3 *>(vert_normals), mesh->verts_num});
2264 }
2265 if (loop_normals_needed) {
2266 const blender::short2 *clnors = static_cast<const blender::short2 *>(
2267 CustomData_get_layer(&mesh->corner_data, CD_CUSTOMLOOPNORMAL));
2268 const AttributeAccessor attributes = mesh->attributes();
2269 const VArraySpan sharp_edges = *attributes.lookup<bool>("sharp_edge", AttrDomain::Edge);
2270 const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", AttrDomain::Face);
2271 mesh::normals_calc_corners(
2272 positions,
2273 edges,
2274 faces,
2275 corner_verts,
2276 corner_edges,
2277 mesh->corner_to_face_map(),
2278 {reinterpret_cast<blender::float3 *>(vert_normals), mesh->verts_num},
2279 {reinterpret_cast<blender::float3 *>(face_normals), faces.size()},
2280 sharp_edges,
2281 sharp_faces,
2282 clnors,
2283 nullptr,
2284 {reinterpret_cast<blender::float3 *>(r_loop_normals), corner_verts.size()});
2285 }
2286
2287 if (free_vert_normals) {
2288 MEM_freeN(vert_normals);
2289 }
2290 if (free_face_normals) {
2291 MEM_freeN(face_normals);
2292 }
2293}
2294
2295/************************* raw coords ************************/
2296
2297void BKE_keyblock_update_from_vertcos(const Object *ob, KeyBlock *kb, const float (*vertCos)[3])
2298{
2299 const float(*co)[3] = vertCos;
2300 float *fp = static_cast<float *>(kb->data);
2301 int tot, a;
2302
2303#ifndef NDEBUG
2304 if (ob->type == OB_LATTICE) {
2305 Lattice *lt = static_cast<Lattice *>(ob->data);
2306 BLI_assert((lt->pntsu * lt->pntsv * lt->pntsw) == kb->totelem);
2307 }
2308 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
2309 Curve *cu = static_cast<Curve *>(ob->data);
2311 }
2312 else if (ob->type == OB_MESH) {
2313 Mesh *mesh = static_cast<Mesh *>(ob->data);
2314 BLI_assert(mesh->verts_num == kb->totelem);
2315 }
2316 else {
2317 BLI_assert(0 == kb->totelem);
2318 }
2319#endif
2320
2321 tot = kb->totelem;
2322 if (tot == 0) {
2323 return;
2324 }
2325
2326 /* Copy coords to key-block. */
2327 if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
2328 for (a = 0; a < tot; a++, fp += 3, co++) {
2329 copy_v3_v3(fp, *co);
2330 }
2331 }
2332 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
2333 const Curve *cu = (const Curve *)ob->data;
2334 const BezTriple *bezt;
2335 const BPoint *bp;
2336
2337 LISTBASE_FOREACH (const Nurb *, nu, &cu->nurb) {
2338 if (nu->bezt) {
2339 for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
2340 for (int i = 0; i < 3; i++, co++) {
2341 copy_v3_v3(&fp[i * 3], *co);
2342 }
2344 }
2345 }
2346 else {
2347 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, co++) {
2348 copy_v3_v3(fp, *co);
2350 }
2351 }
2352 }
2353 }
2354}
2355
2356void BKE_keyblock_convert_from_vertcos(const Object *ob, KeyBlock *kb, const float (*vertCos)[3])
2357{
2358 int tot = 0, elemsize;
2359
2360 MEM_SAFE_FREE(kb->data);
2361
2362 /* Count of vertex coords in array */
2363 if (ob->type == OB_MESH) {
2364 const Mesh *mesh = (const Mesh *)ob->data;
2365 tot = mesh->verts_num;
2366 elemsize = mesh->key->elemsize;
2367 }
2368 else if (ob->type == OB_LATTICE) {
2369 const Lattice *lt = (const Lattice *)ob->data;
2370 tot = lt->pntsu * lt->pntsv * lt->pntsw;
2371 elemsize = lt->key->elemsize;
2372 }
2373 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
2374 const Curve *cu = (const Curve *)ob->data;
2375 elemsize = cu->key->elemsize;
2377 }
2378
2379 if (tot == 0) {
2380 return;
2381 }
2382
2383 kb->data = MEM_mallocN(tot * elemsize, __func__);
2384
2385 /* Copy coords to key-block. */
2386 BKE_keyblock_update_from_vertcos(ob, kb, vertCos);
2387}
2388
2390{
2391 float(*vertCos)[3], (*co)[3];
2392 const float *fp = static_cast<const float *>(kb->data);
2393 int tot = 0, a;
2394
2395 /* Count of vertex coords in array */
2396 if (ob->type == OB_MESH) {
2397 const Mesh *mesh = (const Mesh *)ob->data;
2398 tot = mesh->verts_num;
2399 }
2400 else if (ob->type == OB_LATTICE) {
2401 const Lattice *lt = (const Lattice *)ob->data;
2402 tot = lt->pntsu * lt->pntsv * lt->pntsw;
2403 }
2404 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
2405 const Curve *cu = (const Curve *)ob->data;
2406 tot = BKE_nurbList_verts_count(&cu->nurb);
2407 }
2408
2409 if (tot == 0) {
2410 return nullptr;
2411 }
2412
2413 co = vertCos = static_cast<float(*)[3]>(MEM_mallocN(tot * sizeof(*vertCos), __func__));
2414
2415 /* Copy coords to array */
2416 if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
2417 for (a = 0; a < tot; a++, fp += 3, co++) {
2418 copy_v3_v3(*co, fp);
2419 }
2420 }
2421 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
2422 const Curve *cu = (const Curve *)ob->data;
2423 const BezTriple *bezt;
2424 const BPoint *bp;
2425
2426 LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) {
2427 if (nu->bezt) {
2428 for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
2429 for (int i = 0; i < 3; i++, co++) {
2430 copy_v3_v3(*co, &fp[i * 3]);
2431 }
2433 }
2434 }
2435 else {
2436 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, co++) {
2437 copy_v3_v3(*co, fp);
2439 }
2440 }
2441 }
2442 }
2443
2444 return vertCos;
2445}
2446
2447void BKE_keyblock_update_from_offset(const Object *ob, KeyBlock *kb, const float (*ofs)[3])
2448{
2449 int a;
2450 float *fp = static_cast<float *>(kb->data);
2451
2452 if (ELEM(ob->type, OB_MESH, OB_LATTICE)) {
2453 for (a = 0; a < kb->totelem; a++, fp += 3, ofs++) {
2454 add_v3_v3(fp, *ofs);
2455 }
2456 }
2457 else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF)) {
2458 const Curve *cu = (const Curve *)ob->data;
2459 const BezTriple *bezt;
2460 const BPoint *bp;
2461
2462 LISTBASE_FOREACH (const Nurb *, nu, &cu->nurb) {
2463 if (nu->bezt) {
2464 for (a = nu->pntsu, bezt = nu->bezt; a; a--, bezt++) {
2465 for (int i = 0; i < 3; i++, ofs++) {
2466 add_v3_v3(&fp[i * 3], *ofs);
2467 }
2469 }
2470 }
2471 else {
2472 for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a; a--, bp++, ofs++) {
2473 add_v3_v3(fp, *ofs);
2475 }
2476 }
2477 }
2478 }
2479}
2480
2481bool BKE_keyblock_move(Object *ob, int org_index, int new_index)
2482{
2483 Key *key = BKE_key_from_object(ob);
2484 KeyBlock *kb;
2485 const int act_index = ob->shapenr - 1;
2486 const int totkey = key->totkey;
2487 int i;
2488 bool rev, in_range = false;
2489
2490 if (org_index < 0) {
2491 org_index = act_index;
2492 }
2493
2494 CLAMP(new_index, 0, key->totkey - 1);
2495 CLAMP(org_index, 0, key->totkey - 1);
2496
2497 if (new_index == org_index) {
2498 return false;
2499 }
2500
2501 rev = ((new_index - org_index) < 0) ? true : false;
2502
2503 /* We swap 'org' element with its previous/next neighbor (depending on direction of the move)
2504 * repeatedly, until we reach final position.
2505 * This allows us to only loop on the list once! */
2506 for (kb = static_cast<KeyBlock *>(rev ? key->block.last : key->block.first),
2507 i = (rev ? totkey - 1 : 0);
2508 kb;
2509 kb = (rev ? kb->prev : kb->next), rev ? i-- : i++)
2510 {
2511 if (i == org_index) {
2512 in_range = true; /* Start list items swapping... */
2513 }
2514 else if (i == new_index) {
2515 in_range = false; /* End list items swapping. */
2516 }
2517
2518 if (in_range) {
2519 KeyBlock *other_kb = rev ? kb->prev : kb->next;
2520
2521 /* Swap with previous/next list item. */
2522 BLI_listbase_swaplinks(&key->block, kb, other_kb);
2523
2524 /* Swap absolute positions. */
2525 std::swap(kb->pos, other_kb->pos);
2526
2527 kb = other_kb;
2528 }
2529
2530 /* Adjust relative indices, this has to be done on the whole list! */
2531 if (kb->relative == org_index) {
2532 kb->relative = new_index;
2533 }
2534 else if (kb->relative < org_index && kb->relative >= new_index) {
2535 /* remove after, insert before this index */
2536 kb->relative++;
2537 }
2538 else if (kb->relative > org_index && kb->relative <= new_index) {
2539 /* remove before, insert after this index */
2540 kb->relative--;
2541 }
2542 }
2543
2544 /* Need to update active shape number if it's affected,
2545 * same principle as for relative indices above. */
2546 if (org_index == act_index) {
2547 ob->shapenr = new_index + 1;
2548 }
2549 else if (act_index < org_index && act_index >= new_index) {
2550 ob->shapenr++;
2551 }
2552 else if (act_index > org_index && act_index <= new_index) {
2553 ob->shapenr--;
2554 }
2555
2556 /* First key is always refkey, matches interface and BKE_key_sort */
2557 key->refkey = static_cast<KeyBlock *>(key->block.first);
2558
2559 return true;
2560}
2561
2562bool BKE_keyblock_is_basis(const Key *key, const int index)
2563{
2564 const KeyBlock *kb;
2565 int i;
2566
2567 if (key->type == KEY_RELATIVE) {
2568 for (i = 0, kb = static_cast<const KeyBlock *>(key->block.first); kb; i++, kb = kb->next) {
2569 if ((i != index) && (kb->relative == index)) {
2570 return true;
2571 }
2572 }
2573 }
2574
2575 return false;
2576}
2577
2578std::optional<blender::Array<bool>> BKE_keyblock_get_dependent_keys(const Key *key,
2579 const int index)
2580{
2581 if (key->type != KEY_RELATIVE) {
2582 return std::nullopt;
2583 }
2584
2585 const int count = BLI_listbase_count(&key->block);
2586
2587 if (index < 0 || index >= count) {
2588 return std::nullopt;
2589 }
2590
2591 /* Seed the table with the specified key. */
2592 blender::Array<bool> marked(count, false);
2593
2594 marked[index] = true;
2595
2596 /* Iterative breadth-first search through the key list. This method minimizes
2597 * the number of scans through the list and is fail-safe vs reference cycles. */
2598 bool updated, found = false;
2599 int i;
2600
2601 do {
2602 updated = false;
2603
2604 LISTBASE_FOREACH_INDEX (const KeyBlock *, kb, &key->block, i) {
2605 if (!marked[i] && kb->relative >= 0 && kb->relative < count && marked[kb->relative]) {
2606 marked[i] = true;
2607 updated = found = true;
2608 }
2609 }
2610 } while (updated);
2611
2612 if (!found) {
2613 return std::nullopt;
2614 }
2615
2616 /* After the search is complete, exclude the original key. */
2617 marked[index] = false;
2618 return marked;
2619}
int BKE_nurbList_verts_count(const ListBase *nurb)
Definition curve.cc:535
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
support for deformation groups and hooks.
int BKE_object_defgroup_count(const Object *ob)
Definition deform.cc:596
float BKE_defvert_find_weight(const MDeformVert *dvert, int defgroup)
Definition deform.cc:770
int BKE_object_defgroup_name_index(const Object *ob, blender::StringRef name)
Definition deform.cc:585
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition BKE_idtype.hh:32
void outside_lattice(Lattice *lt)
Definition lattice.cc:402
void * BKE_id_new(Main *bmain, short type, const char *name)
Definition lib_id.cc:1482
void BKE_id_blend_write(BlendWriter *writer, ID *id)
Definition lib_id.cc:2560
@ IDWALK_CB_LOOPBACK
@ IDWALK_CB_USER
int BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:120
@ IDWALK_DO_DEPRECATED_POINTERS
#define BKE_LIB_FOREACHID_PROCESS_ID(data_, id_, cb_flag_)
#define BKE_LIB_FOREACHID_PROCESS_ID_NOCHECK(data_, id_, cb_flag_)
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
void BLI_endian_switch_float_array(float *val, int size) ATTR_NONNULL(1)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
void void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:331
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:130
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:251
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
MINLINE int compare_ff(float a, float b, float max_diff)
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
Definition math_vector.c:45
MINLINE void add_v3_v3(float r[3], const float a[3])
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
#define STRNCPY_UTF8(dst, src)
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
#define CLAMP(a, b, c)
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
Definition readfile.cc:4903
#define BLO_read_struct_list(reader, struct_name, list)
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
#define BLO_read_struct(reader, struct_name, ptr_p)
bool BLO_write_is_undo(BlendWriter *writer)
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
#define BLT_I18NCONTEXT_ID_SHAPEKEY
#define DATA_(msgid)
ID and Library types, which are fundamental for SDNA.
#define FILTER_ID_CU_LEGACY
Definition DNA_ID.h:1168
#define FILTER_ID_LT
Definition DNA_ID.h:1174
#define FILTER_ID_ME
Definition DNA_ID.h:1178
@ ID_TAG_EXTERN
Definition DNA_ID.h:788
@ INDEX_ID_KE
Definition DNA_ID.h:1289
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
#define FILTER_ID_KE
Definition DNA_ID.h:1199
@ ID_KE
@ ID_CU_LEGACY
@ ID_ME
@ ID_LT
@ CD_CUSTOMLOOPNORMAL
@ CD_MDEFORMVERT
@ KEY_RELATIVE
@ KEY_NORMAL
@ KEYBLOCK_MUTE
@ KEY_LINEAR
@ KEY_CARDINAL
@ KEY_BSPLINE
@ KEY_CATMULL_ROM
#define KEYELEM_FLOAT_LEN_COORD
#define KEYELEM_ELEM_LEN_BPOINT
#define KEYELEM_FLOAT_LEN_BEZTRIPLE
#define KEYELEM_ELEM_SIZE_CURVE
struct Key Key
#define KEYELEM_FLOAT_LEN_BPOINT
#define KEYELEM_ELEM_LEN_BEZTRIPLE
@ LT_OUTSIDE
Object is a sort of wrapper for general info.
@ OB_SHAPE_LOCK
@ OB_LATTICE
@ OB_SURF
@ OB_MESH
@ OB_CURVES_LEGACY
#define OB_TYPE_SUPPORT_VGROUP(_type)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_VERTS_OF_MESH
local_group_size(16, 16) .push_constant(Type b
StackEntry * from
Lattice lattice
#define offsetof(t, d)
int len
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
int count
#define GS(x)
Definition iris.cc:202
static void shapekey_blend_read_data(BlendDataReader *reader, ID *id)
Definition key.cc:174
void BKE_keyblock_data_set_with_mat4(Key *key, const int shape_index, const float(*coords)[3], const float mat[4][4])
Definition key.cc:1706
void key_curve_normal_weights(float t, float data[4], int type)
Definition key.cc:418
#define IPO_FLOAT
Definition key.cc:143
static void key_evaluate_relative(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, float **per_keyblock_weights, const int mode)
Definition key.cc:869
void BKE_keyblock_curve_data_transform(const ListBase *nurb, const float mat[4][4], const void *src_data, void *dst_data)
Definition key.cc:2086
void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, Mesh *mesh, float(*r_vert_normals)[3], float(*r_face_normals)[3], float(*r_loop_normals)[3])
Definition key.cc:2210
KeyBlock * BKE_keyblock_from_object(Object *ob)
Definition key.cc:1905
static void flerp(int tot, float *in, const float *f0, const float *f1, const float *f2, const float *f3, const float *t)
Definition key.cc:596
void BKE_keyblock_convert_to_lattice(const KeyBlock *kb, Lattice *lt)
Definition key.cc:2018
Key ** BKE_key_from_id_p(ID *id)
Definition key.cc:1775
std::optional< std::string > BKE_keyblock_curval_rnapath_get(const Key *key, const KeyBlock *kb)
Definition key.cc:1958
static ID ** shapekey_owner_pointer_get(ID *id, const bool debug_relationship_assert)
Definition key.cc:106
void BKE_keyblock_curve_data_set_with_mat4(Key *key, const ListBase *nurb, const int shape_index, const void *data, const float mat[4][4])
Definition key.cc:1733
size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, const int shape_index)
Definition key.cc:1669
void BKE_key_free_nolib(Key *key)
Definition key.cc:246
int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index)
Definition key.cc:1650
#define IPO_BEZTRIPLE
Definition key.cc:144
Key * BKE_key_add(Main *bmain, ID *id)
Definition key.cc:256
std::optional< blender::Array< bool > > BKE_keyblock_get_dependent_keys(const Key *key, const int index)
Definition key.cc:2578
bool BKE_key_idtype_support(const short id_type)
Definition key.cc:1763
static void keyblock_free_per_block_weights(Key *key, float **per_keyblock_weights, WeightsArrayCache *cache)
Definition key.cc:1364
#define KEY_MODE_BPOINT
Definition key.cc:232
KeyBlock * BKE_keyblock_add(Key *key, const char *name)
Definition key.cc:1831
KeyBlock * BKE_keyblock_from_object_reference(Object *ob)
Definition key.cc:1912
bool BKE_keyblock_move(Object *ob, int org_index, int new_index)
Definition key.cc:2481
void BKE_keyblock_update_from_mesh(const Mesh *mesh, KeyBlock *kb)
Definition key.cc:2173
static void shapekey_foreach_id(ID *id, LibraryForeachIDData *data)
Definition key.cc:94
static float * get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cache)
Definition key.cc:1270
static bool key_pointer_size(const Key *key, const int mode, int *r_poinsize, int *r_ofs, int *r_step)
Definition key.cc:655
void BKE_keyblock_data_set(Key *key, const int shape_index, const void *data)
Definition key.cc:1748
static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const int tot)
Definition key.cc:1441
void BKE_key_free_data(Key *key)
Definition key.cc:241
void BKE_keyblock_update_from_offset(const Object *ob, KeyBlock *kb, const float(*ofs)[3])
Definition key.cc:2447
void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *, ListBase *nurb)
Definition key.cc:2163
static void do_key(const int start, int end, const int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, const int mode)
Definition key.cc:1003
KeyBlock * BKE_keyblock_add_ctime(Key *key, const char *name, const bool do_force)
Definition key.cc:1878
int BKE_keyblock_curve_element_count(const ListBase *nurb)
Definition key.cc:2029
void BKE_keyblock_data_get(const Key *key, float(*arr)[3])
Definition key.cc:1701
void BKE_keyblock_convert_from_mesh(const Mesh *mesh, const Key *key, KeyBlock *kb)
Definition key.cc:2186
static void switch_endian_keyblock(Key *key, KeyBlock *kb)
Definition key.cc:147
static void shapekey_copy_data(Main *, std::optional< Library * >, ID *id_dst, const ID *id_src, const int)
Definition key.cc:58
size_t BKE_keyblock_element_calc_size(const Key *key)
Definition key.cc:1674
void BKE_keyblock_update_from_curve(const Curve *, KeyBlock *kb, const ListBase *nurb)
Definition key.cc:2048
float * BKE_key_evaluate_object_ex(Object *ob, int *r_totelem, float *arr, size_t arr_size, ID *obdata)
Definition key.cc:1522
KeyBlock * BKE_keyblock_find_by_index(Key *key, int index)
Definition key.cc:1923
static void do_curve_key(Object *ob, Key *key, char *out, const int tot)
Definition key.cc:1461
void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
copy shape-key attributes, but not key data or name/UID.
Definition key.cc:1947
void BKE_keyblock_convert_from_curve(const Curve *cu, KeyBlock *kb, const ListBase *nurb)
Definition key.cc:2117
#define KEY_MODE_BEZTRIPLE
Definition key.cc:233
void key_curve_tangent_weights(float t, float data[4], int type)
Definition key.cc:380
KeyBlock * BKE_keyblock_find_name(Key *key, const char name[])
Definition key.cc:1932
void BKE_keyblock_convert_from_lattice(const Lattice *lt, KeyBlock *kb)
Definition key.cc:1992
static void keyblock_data_convert_to_curve(const float *fp, ListBase *nurb, const int totpoint)
Definition key.cc:2135
float * BKE_key_evaluate_object(Object *ob, int *r_totelem)
Definition key.cc:1645
static void do_mesh_key(Object *ob, Key *key, char *out, const int tot)
Definition key.cc:1392
static char * key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata)
Definition key.cc:620
static void keyblock_data_convert_to_lattice(const float(*fp)[3], BPoint *bpoint, const int totpoint)
Definition key.cc:2009
static void do_latt_key(Object *ob, Key *key, char *out, const int tot)
Definition key.cc:1485
static void cp_key(const int start, int end, const int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, const int mode)
Definition key.cc:692
static void shapekey_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition key.cc:118
void BKE_keyblock_update_from_lattice(const Lattice *lt, KeyBlock *kb)
Definition key.cc:1972
int BKE_keyblock_element_count(const Key *key)
Definition key.cc:1664
#define KEY_MODE_DUMMY
Definition key.cc:231
static void rel_flerp(int tot, float *in, const float *ref, const float *out, float fac)
Definition key.cc:611
static float ** keyblock_get_per_block_weights(Object *ob, Key *key, WeightsArrayCache *cache)
Definition key.cc:1346
IDTypeInfo IDType_ID_KE
Definition key.cc:198
void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, float(*vert_positions)[3], const int totvert)
Definition key.cc:2202
Key ** BKE_key_from_object_p(Object *ob)
Definition key.cc:1811
void BKE_keyblock_convert_from_vertcos(const Object *ob, KeyBlock *kb, const float(*vertCos)[3])
Definition key.cc:2356
static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, const int tot)
Definition key.cc:1420
Key * BKE_key_from_id(ID *id)
Definition key.cc:1800
KeyBlock * BKE_keyblock_find_uid(Key *key, const int uid)
Definition key.cc:1937
static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
Definition key.cc:452
void BKE_key_sort(Key *key)
Definition key.cc:308
bool BKE_keyblock_is_basis(const Key *key, const int index)
Definition key.cc:2562
void BKE_keyblock_update_from_vertcos(const Object *ob, KeyBlock *kb, const float(*vertCos)[3])
Definition key.cc:2297
static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const int start, int end, char *out, const int tot)
Definition key.cc:829
Key * BKE_key_from_object(Object *ob)
Definition key.cc:1820
float(* BKE_keyblock_convert_to_vertcos(const Object *ob, const KeyBlock *kb))[3]
Definition key.cc:2389
static void shapekey_free_data(ID *id)
Definition key.cc:83
void key_curve_position_weights(float t, float data[4], int type)
Definition key.cc:339
void BKE_keyblock_data_get_from_shape(const Key *key, float(*arr)[3], const int shape_index)
Definition key.cc:1686
static void shapekey_blend_read_after_liblink(BlendLibReader *, ID *id)
Definition key.cc:190
#define IPO_BPOINT
Definition key.cc:145
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:45
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
void *(* MEM_dupallocN)(const void *vmemh)
Definition mallocn.cc:39
ccl_device_inline float2 floor(const float2 a)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition rna_path.cc:1166
unsigned char uint8_t
Definition stdint.h:78
float co[3]
CustomData vdata
float vec[4]
float vec[3][3]
struct VFont * vfont
struct Key * key
ListBase nurb
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
struct KeyBlock * prev
char name[64]
float slidermax
float slidermin
float curval
struct KeyBlock * next
char vgroup[64]
short relative
void * data
ID * from
int totkey
float ctime
char elemstr[32]
int uidgen
int elemsize
char type
ListBase block
KeyBlock * refkey
struct Key * key
struct MDeformVert * dvert
struct BPoint * def
void * last
void * first
struct Key * key
int verts_num
struct Nurb * next
BezTriple * bezt
BPoint * bp
int num_defgroup_weights
Definition key.cc:237
float ** defgroup_weights
Definition key.cc:238
#define N_(msgid)
PointerRNA * ptr
Definition wm_files.cc:4126
uint8_t flag
Definition wm_window.cc:138