Blender V4.5
ipo.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
8
9/* NOTE:
10 *
11 * This file is no longer used to provide tools for the deprecated IPO system. Instead, it
12 * is only used to house the conversion code to the new system.
13 *
14 * -- Joshua Leung, Jan 2009
15 */
16
17#include <cmath>
18#include <cstddef>
19#include <cstdio>
20#include <cstring>
21
22/* since we have versioning code here */
23#define DNA_DEPRECATED_ALLOW
24
25#include "DNA_anim_types.h"
26#include "DNA_camera_types.h"
28#include "DNA_ipo_types.h"
29#include "DNA_key_types.h"
30#include "DNA_light_types.h"
31#include "DNA_material_types.h"
32#include "DNA_nla_types.h"
33#include "DNA_object_types.h"
34#include "DNA_scene_types.h"
35#include "DNA_sequence_types.h"
36#include "DNA_texture_types.h"
37#include "DNA_world_types.h"
38
39#include "BLI_dynstr.h"
40#include "BLI_endian_switch.h"
41#include "BLI_listbase.h"
42#include "BLI_string.h"
43#include "BLI_string_utils.hh"
44#include "BLI_utildefines.h"
45
46#include "BLT_translation.hh"
47
48#include "BKE_action.hh"
49#include "BKE_anim_data.hh"
50#include "BKE_fcurve.hh"
51#include "BKE_fcurve_driver.h"
52#include "BKE_global.hh"
53#include "BKE_idtype.hh"
54#include "BKE_ipo.h"
55#include "BKE_key.hh"
56#include "BKE_lib_id.hh"
57#include "BKE_lib_query.hh"
58#include "BKE_main.hh"
59#include "BKE_nla.hh"
60
61#include "ANIM_action.hh"
62#include "ANIM_versioning.hh"
63
64#include "CLG_log.h"
65
66#include "MEM_guardedalloc.h"
67
68#include "SEQ_iterator.hh"
69
70#include "BLO_read_write.hh"
71
72#ifdef WIN32
73# include "BLI_math_base.h" /* M_PI */
74#endif
75
76static CLG_LogRef LOG = {"bke.ipo"};
77
78using namespace blender;
79
80static void ipo_free_data(ID *id)
81{
82 Ipo *ipo = (Ipo *)id;
83
84 IpoCurve *icu, *icn;
85 int n = 0;
86
87 for (icu = static_cast<IpoCurve *>(ipo->curve.first); icu; icu = icn) {
88 icn = icu->next;
89 n++;
90
91 if (icu->bezt) {
92 MEM_freeN(icu->bezt);
93 }
94 if (icu->bp) {
95 MEM_freeN(icu->bp);
96 }
97 if (icu->driver) {
98 MEM_freeN(icu->driver);
99 }
100
101 BLI_freelinkN(&ipo->curve, icu);
102 }
103
104 if (G.debug & G_DEBUG) {
105 printf("Freed %d (Unconverted) Ipo-Curves from IPO '%s'\n", n, ipo->id.name + 2);
106 }
107}
108
110{
111 Ipo *ipo = reinterpret_cast<Ipo *>(id);
113
115 LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
116 if (icu->driver) {
118 }
119 }
120 }
121}
122
123static void ipo_blend_read_data(BlendDataReader *reader, ID *id)
124{
125 Ipo *ipo = (Ipo *)id;
126
127 BLO_read_struct_list(reader, IpoCurve, &(ipo->curve));
128
129 LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
130 BLO_read_struct_array(reader, BezTriple, icu->totvert, &icu->bezt);
131 BLO_read_struct_array(reader, BPoint, icu->totvert, &icu->bp);
132 BLO_read_struct(reader, IpoDriver, &icu->driver);
133
134 /* Undo generic endian switching. */
136 BLI_endian_switch_int16(&icu->blocktype);
137 if (icu->driver != nullptr) {
138
139 /* Undo generic endian switching. */
141 BLI_endian_switch_int16(&icu->blocktype);
142 if (icu->driver != nullptr) {
143 BLI_endian_switch_int16(&icu->driver->blocktype);
144 }
145 }
146 }
147
148 /* Undo generic endian switching. */
151 if (icu->driver != nullptr) {
152 BLI_endian_switch_int16(&icu->driver->blocktype);
153 }
154 }
155 }
156 }
157
158 /* Undo generic endian switching. */
161 }
162}
163
165 /*id_code*/ Ipo::id_type,
166 /*id_filter*/ FILTER_ID_IP,
167 /*dependencies_id_types*/ 0,
168 /*main_listbase_index*/ INDEX_ID_IP,
169 /*struct_size*/ sizeof(Ipo),
170 /*name*/ "Ipo",
171 /*name_plural*/ N_("ipos"),
172 /*translation_context*/ "",
174 /*asset_type_info*/ nullptr,
175
176 /*init_data*/ nullptr,
177 /*copy_data*/ nullptr,
178 /*free_data*/ ipo_free_data,
179 /*make_local*/ nullptr,
180 /*foreach_id*/ ipo_foreach_id,
181 /*foreach_cache*/ nullptr,
182 /*foreach_path*/ nullptr,
183 /*owner_pointer_get*/ nullptr,
184
185 /*blend_write*/ nullptr,
186 /*blend_read_data*/ ipo_blend_read_data,
187 /*blend_read_after_liblink*/ nullptr,
188
189 /*blend_read_undo_preserve*/ nullptr,
190
191 /*lib_override_apply_post*/ nullptr,
192};
193
194/* *************************************************** */
195/* Old-Data Freeing Tools */
196
197/* *************************************************** */
198/* ADRCODE to RNA-Path Conversion Code - Special (Bitflags) */
199
200/* Mapping Table for bitflag <-> RNA path */
202 int bit;
203 const char *path;
205};
206
207/* ----------------- */
208/* Mapping Tables to use bits <-> RNA paths */
209
210/* Object layers */
212 {(1 << 0), "layers", 0}, {(1 << 1), "layers", 1}, {(1 << 2), "layers", 2},
213 {(1 << 3), "layers", 3}, {(1 << 4), "layers", 4}, {(1 << 5), "layers", 5},
214 {(1 << 6), "layers", 6}, {(1 << 7), "layers", 7}, {(1 << 8), "layers", 8},
215 {(1 << 9), "layers", 9}, {(1 << 10), "layers", 10}, {(1 << 11), "layers", 11},
216 {(1 << 12), "layers", 12}, {(1 << 13), "layers", 13}, {(1 << 14), "layers", 14},
217 {(1 << 15), "layers", 15}, {(1 << 16), "layers", 16}, {(1 << 17), "layers", 17},
218 {(1 << 18), "layers", 18}, {(1 << 19), "layers", 19},
219};
220
221/* ----------------- */
222
223/* quick macro for returning the appropriate array for adrcode_bitmaps_to_paths() */
224#define RET_ABP(items) \
225 { \
226 *tot = ARRAY_SIZE(items); \
227 return items; \
228 } \
229 (void)0
230
231/* This function checks if a `blocktype+adrcode` combination, returning a mapping table. */
232static AdrBit2Path *adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *tot)
233{
234 /* Object layers */
235 if ((blocktype == ID_OB) && (adrcode == OB_LAY)) {
237 }
238 /* XXX TODO: add other types... */
239
240 /* Normal curve */
241 return nullptr;
242}
243#undef RET_ABP
244
245/* *************************************************** */
246/* ADRCODE to RNA-Path Conversion Code - Standard */
247
248/* Object types */
249static const char *ob_adrcodes_to_paths(int adrcode, int *r_array_index)
250{
251 /* Set array index like this in-case nothing sets it correctly. */
252 *r_array_index = 0;
253
254 /* result depends on adrcode */
255 switch (adrcode) {
256 case OB_LOC_X:
257 *r_array_index = 0;
258 return "location";
259 case OB_LOC_Y:
260 *r_array_index = 1;
261 return "location";
262 case OB_LOC_Z:
263 *r_array_index = 2;
264 return "location";
265 case OB_DLOC_X:
266 *r_array_index = 0;
267 return "delta_location";
268 case OB_DLOC_Y:
269 *r_array_index = 1;
270 return "delta_location";
271 case OB_DLOC_Z:
272 *r_array_index = 2;
273 return "delta_location";
274
275 case OB_ROT_X:
276 *r_array_index = 0;
277 return "rotation_euler";
278 case OB_ROT_Y:
279 *r_array_index = 1;
280 return "rotation_euler";
281 case OB_ROT_Z:
282 *r_array_index = 2;
283 return "rotation_euler";
284 case OB_DROT_X:
285 *r_array_index = 0;
286 return "delta_rotation_euler";
287 case OB_DROT_Y:
288 *r_array_index = 1;
289 return "delta_rotation_euler";
290 case OB_DROT_Z:
291 *r_array_index = 2;
292 return "delta_rotation_euler";
293
294 case OB_SIZE_X:
295 *r_array_index = 0;
296 return "scale";
297 case OB_SIZE_Y:
298 *r_array_index = 1;
299 return "scale";
300 case OB_SIZE_Z:
301 *r_array_index = 2;
302 return "scale";
303 case OB_DSIZE_X:
304 *r_array_index = 0;
305 return "delta_scale";
306 case OB_DSIZE_Y:
307 *r_array_index = 1;
308 return "delta_scale";
309 case OB_DSIZE_Z:
310 *r_array_index = 2;
311 return "delta_scale";
312 case OB_COL_R:
313 *r_array_index = 0;
314 return "color";
315 case OB_COL_G:
316 *r_array_index = 1;
317 return "color";
318 case OB_COL_B:
319 *r_array_index = 2;
320 return "color";
321 case OB_COL_A:
322 *r_array_index = 3;
323 return "color";
324#if 0
325 case OB_PD_FSTR:
326 if (ob->pd) {
327 poin = &(ob->pd->f_strength);
328 }
329 break;
330 case OB_PD_FFALL:
331 if (ob->pd) {
332 poin = &(ob->pd->f_power);
333 }
334 break;
335 case OB_PD_SDAMP:
336 if (ob->pd) {
337 poin = &(ob->pd->pdef_damp);
338 }
339 break;
340 case OB_PD_RDAMP:
341 if (ob->pd) {
342 poin = &(ob->pd->pdef_rdamp);
343 }
344 break;
345 case OB_PD_PERM:
346 if (ob->pd) {
347 poin = &(ob->pd->pdef_perm);
348 }
349 break;
350 case OB_PD_FMAXD:
351 if (ob->pd) {
352 poin = &(ob->pd->maxdist);
353 }
354 break;
355#endif
356 }
357
358 return nullptr;
359}
360
361/* PoseChannel types
362 * NOTE: pchan name comes from 'actname' added earlier...
363 */
364static const char *pchan_adrcodes_to_paths(int adrcode, int *r_array_index)
365{
366 /* Set array index like this in-case nothing sets it correctly. */
367 *r_array_index = 0;
368
369 /* result depends on adrcode */
370 switch (adrcode) {
371 case AC_QUAT_W:
372 *r_array_index = 0;
373 return "rotation_quaternion";
374 case AC_QUAT_X:
375 *r_array_index = 1;
376 return "rotation_quaternion";
377 case AC_QUAT_Y:
378 *r_array_index = 2;
379 return "rotation_quaternion";
380 case AC_QUAT_Z:
381 *r_array_index = 3;
382 return "rotation_quaternion";
383
384 case AC_EUL_X:
385 *r_array_index = 0;
386 return "rotation_euler";
387 case AC_EUL_Y:
388 *r_array_index = 1;
389 return "rotation_euler";
390 case AC_EUL_Z:
391 *r_array_index = 2;
392 return "rotation_euler";
393
394 case AC_LOC_X:
395 *r_array_index = 0;
396 return "location";
397 case AC_LOC_Y:
398 *r_array_index = 1;
399 return "location";
400 case AC_LOC_Z:
401 *r_array_index = 2;
402 return "location";
403
404 case AC_SIZE_X:
405 *r_array_index = 0;
406 return "scale";
407 case AC_SIZE_Y:
408 *r_array_index = 1;
409 return "scale";
410 case AC_SIZE_Z:
411 *r_array_index = 2;
412 return "scale";
413 }
414
415 /* for debugging only */
416 CLOG_ERROR(&LOG, "unmatched PoseChannel setting (code %d)", adrcode);
417 return nullptr;
418}
419
420/* Constraint types */
421static const char *constraint_adrcodes_to_paths(int adrcode, int *r_array_index)
422{
423 /* Set array index like this in-case nothing sets it correctly. */
424 *r_array_index = 0;
425
426 /* result depends on adrcode */
427 switch (adrcode) {
428 case CO_ENFORCE:
429 return "influence";
430 case CO_HEADTAIL:
431 /* XXX this needs to be wrapped in RNA.. probably then this path will be invalid. */
432 return "data.head_tail";
433 }
434
435 return nullptr;
436}
437
438/* ShapeKey types
439 * NOTE: as we don't have access to the keyblock where the data comes from (for now),
440 * we'll just use numerical indices for now...
441 */
442static char *shapekey_adrcodes_to_paths(ID *id, int adrcode, int * /*r_array_index*/)
443{
444 static char buf[128];
445
446 /* block will be attached to ID_KE block... */
447 if (adrcode == 0) {
448 /* adrcode=0 was the misnamed "speed" curve (now "evaluation time") */
449 STRNCPY(buf, "eval_time");
450 }
451 else {
452 /* Find the name of the ShapeKey (i.e. KeyBlock) to look for */
453 Key *key = (Key *)id;
454 KeyBlock *kb = BKE_keyblock_find_by_index(key, adrcode);
455
456 /* setting that we alter is the "value" (i.e. keyblock.curval) */
457 if (kb) {
458 /* Use the keyblock name, escaped, so that path lookups for this will work */
459 char kb_name_esc[sizeof(kb->name) * 2];
460 BLI_str_escape(kb_name_esc, kb->name, sizeof(kb_name_esc));
461 SNPRINTF(buf, "key_blocks[\"%s\"].value", kb_name_esc);
462 }
463 else {
464 /* Fallback - Use the adrcode as index directly, so that this can be manually fixed */
465 SNPRINTF(buf, "key_blocks[%d].value", adrcode);
466 }
467 }
468 return buf;
469}
470
471/* MTex (Texture Slot) types */
472static const char *mtex_adrcodes_to_paths(int adrcode, int * /*r_array_index*/)
473{
474 const char *base = nullptr, *prop = nullptr;
475 static char buf[128];
476
477 /* base part of path */
478 if (adrcode & MA_MAP1) {
479 base = "textures[0]";
480 }
481 else if (adrcode & MA_MAP2) {
482 base = "textures[1]";
483 }
484 else if (adrcode & MA_MAP3) {
485 base = "textures[2]";
486 }
487 else if (adrcode & MA_MAP4) {
488 base = "textures[3]";
489 }
490 else if (adrcode & MA_MAP5) {
491 base = "textures[4]";
492 }
493 else if (adrcode & MA_MAP6) {
494 base = "textures[5]";
495 }
496 else if (adrcode & MA_MAP7) {
497 base = "textures[6]";
498 }
499 else if (adrcode & MA_MAP8) {
500 base = "textures[7]";
501 }
502 else if (adrcode & MA_MAP9) {
503 base = "textures[8]";
504 }
505 else if (adrcode & MA_MAP10) {
506 base = "textures[9]";
507 }
508 else if (adrcode & MA_MAP11) {
509 base = "textures[10]";
510 }
511 else if (adrcode & MA_MAP12) {
512 base = "textures[11]";
513 }
514 else if (adrcode & MA_MAP13) {
515 base = "textures[12]";
516 }
517 else if (adrcode & MA_MAP14) {
518 base = "textures[13]";
519 }
520 else if (adrcode & MA_MAP15) {
521 base = "textures[14]";
522 }
523 else if (adrcode & MA_MAP16) {
524 base = "textures[15]";
525 }
526 else if (adrcode & MA_MAP17) {
527 base = "textures[16]";
528 }
529 else if (adrcode & MA_MAP18) {
530 base = "textures[17]";
531 }
532
533 /* property identifier for path */
534 adrcode = (adrcode & (MA_MAP1 - 1));
535 switch (adrcode) {
536#if 0 /* XXX these are not wrapped in RNA yet! */
537 case MAP_OFS_X:
538 poin = &(mtex->ofs[0]);
539 break;
540 case MAP_OFS_Y:
541 poin = &(mtex->ofs[1]);
542 break;
543 case MAP_OFS_Z:
544 poin = &(mtex->ofs[2]);
545 break;
546 case MAP_SIZE_X:
547 poin = &(mtex->size[0]);
548 break;
549 case MAP_SIZE_Y:
550 poin = &(mtex->size[1]);
551 break;
552 case MAP_SIZE_Z:
553 poin = &(mtex->size[2]);
554 break;
555 case MAP_R:
556 poin = &(mtex->r);
557 break;
558 case MAP_G:
559 poin = &(mtex->g);
560 break;
561 case MAP_B:
562 poin = &(mtex->b);
563 break;
564 case MAP_DVAR:
565 poin = &(mtex->def_var);
566 break;
567 case MAP_COLF:
568 poin = &(mtex->colfac);
569 break;
570 case MAP_NORF:
571 poin = &(mtex->norfac);
572 break;
573 case MAP_VARF:
574 poin = &(mtex->varfac);
575 break;
576#endif
577 case MAP_DISP:
578 prop = "warp_factor";
579 break;
580 }
581
582 /* only build and return path if there's a property */
583 if (prop) {
584 SNPRINTF(buf, "%s.%s", base, prop);
585 return buf;
586 }
587
588 return nullptr;
589}
590
591/* Texture types */
592static const char *texture_adrcodes_to_paths(int adrcode, int *r_array_index)
593{
594 /* Set array index like this in-case nothing sets it correctly. */
595 *r_array_index = 0;
596
597 /* result depends on adrcode */
598 switch (adrcode) {
599 case TE_NSIZE:
600 return "noise_size";
601 case TE_TURB:
602 return "turbulence";
603
604 case TE_NDEPTH: /* XXX texture RNA undefined */
605 // poin= &(tex->noisedepth); *type= IPO_SHORT; break;
606 break;
607 case TE_NTYPE: /* XXX texture RNA undefined */
608 // poin= &(tex->noisetype); *type= IPO_SHORT; break;
609 break;
610
611 case TE_N_BAS1:
612 return "noise_basis";
613 case TE_N_BAS2:
614 return "noise_basis"; /* XXX this is not yet defined in RNA... */
615
616 /* voronoi */
617 case TE_VNW1:
618 *r_array_index = 0;
619 return "feature_weights";
620 case TE_VNW2:
621 *r_array_index = 1;
622 return "feature_weights";
623 case TE_VNW3:
624 *r_array_index = 2;
625 return "feature_weights";
626 case TE_VNW4:
627 *r_array_index = 3;
628 return "feature_weights";
629 case TE_VNMEXP:
630 return "minkovsky_exponent";
631 case TE_VN_DISTM:
632 return "distance_metric";
633 case TE_VN_COLT:
634 return "color_type";
635
636 /* distorted noise / voronoi */
637 case TE_ISCA:
638 return "noise_intensity";
639
640 /* distorted noise */
641 case TE_DISTA:
642 return "distortion_amount";
643
644 /* musgrave */
645 case TE_MG_TYP: /* XXX texture RNA undefined */
646 // poin= &(tex->stype); *type= IPO_SHORT; break;
647 break;
648 case TE_MGH:
649 return "highest_dimension";
650 case TE_MG_LAC:
651 return "lacunarity";
652 case TE_MG_OCT:
653 return "octaves";
654 case TE_MG_OFF:
655 return "offset";
656 case TE_MG_GAIN:
657 return "gain";
658
659 case TE_COL_R:
660 *r_array_index = 0;
661 return "rgb_factor";
662 case TE_COL_G:
663 *r_array_index = 1;
664 return "rgb_factor";
665 case TE_COL_B:
666 *r_array_index = 2;
667 return "rgb_factor";
668
669 case TE_BRIGHT:
670 return "brightness";
671 case TE_CONTRA:
672 return "contrast";
673 }
674
675 return nullptr;
676}
677
678/* Material Types */
679static const char *material_adrcodes_to_paths(int adrcode, int *r_array_index)
680{
681 /* Set array index like this in-case nothing sets it correctly. */
682 *r_array_index = 0;
683
684 /* result depends on adrcode */
685 switch (adrcode) {
686 case MA_COL_R:
687 *r_array_index = 0;
688 return "diffuse_color";
689 case MA_COL_G:
690 *r_array_index = 1;
691 return "diffuse_color";
692 case MA_COL_B:
693 *r_array_index = 2;
694 return "diffuse_color";
695
696 case MA_SPEC_R:
697 *r_array_index = 0;
698 return "specular_color";
699 case MA_SPEC_G:
700 *r_array_index = 1;
701 return "specular_color";
702 case MA_SPEC_B:
703 *r_array_index = 2;
704 return "specular_color";
705
706 case MA_MIR_R:
707 *r_array_index = 0;
708 return "mirror_color";
709 case MA_MIR_G:
710 *r_array_index = 1;
711 return "mirror_color";
712 case MA_MIR_B:
713 *r_array_index = 2;
714 return "mirror_color";
715
716 case MA_ALPHA:
717 return "alpha";
718
719 case MA_REF:
720 return "diffuse_intensity";
721
722 case MA_EMIT:
723 return "emit";
724
725 case MA_AMB:
726 return "ambient";
727
728 case MA_SPEC:
729 return "specular_intensity";
730
731 case MA_HARD:
732 return "specular_hardness";
733
734 case MA_SPTR:
735 return "specular_opacity";
736
737 case MA_IOR:
738 return "ior";
739
740 case MA_HASIZE:
741 return "halo.size";
742
743 case MA_TRANSLU:
744 return "translucency";
745
746 case MA_RAYM:
747 return "raytrace_mirror.reflect";
748
749 case MA_FRESMIR:
750 return "raytrace_mirror.fresnel";
751
752 case MA_FRESMIRI:
753 return "raytrace_mirror.fresnel_factor";
754
755 case MA_FRESTRA:
756 return "raytrace_transparency.fresnel";
757
758 case MA_FRESTRAI:
759 return "raytrace_transparency.fresnel_factor";
760
761 case MA_ADD:
762 return "halo.add";
763
764 default: /* for now, we assume that the others were MTex channels */
765 return mtex_adrcodes_to_paths(adrcode, r_array_index);
766 }
767
768 return nullptr;
769}
770
771/* Camera Types */
772static const char *camera_adrcodes_to_paths(int adrcode, int *r_array_index)
773{
774 /* Set array index like this in-case nothing sets it correctly. */
775 *r_array_index = 0;
776
777 /* result depends on adrcode */
778 switch (adrcode) {
779 case CAM_LENS:
780#if 0 /* XXX this cannot be resolved easily... \
781 * perhaps we assume camera is perspective (works for most cases... */
782 if (ca->type == CAM_ORTHO) {
783 return "ortho_scale";
784 }
785 else {
786 return "lens";
787 }
788#else /* XXX lazy hack for now... */
789 return "lens";
790#endif /* XXX this cannot be resolved easily */
791
792 case CAM_STA:
793 return "clip_start";
794 case CAM_END:
795 return "clip_end";
796
797#if 0 /* XXX these are not defined in RNA */
798 case CAM_YF_APERT:
799 poin = &(ca->YF_aperture);
800 break;
801 case CAM_YF_FDIST:
802 poin = &(ca->dof_distance);
803 break;
804#endif /* XXX these are not defined in RNA */
805
806 case CAM_SHIFT_X:
807 return "shift_x";
808 case CAM_SHIFT_Y:
809 return "shift_y";
810 }
811
812 /* unrecognized adrcode, or not-yet-handled ones! */
813 return nullptr;
814}
815
816/* Light Types */
817static const char *light_adrcodes_to_paths(int adrcode, int *r_array_index)
818{
819 /* Set array index like this in-case nothing sets it correctly. */
820 *r_array_index = 0;
821
822 /* result depends on adrcode */
823 switch (adrcode) {
824 case LA_ENERGY:
825 return "energy";
826
827 case LA_COL_R:
828 *r_array_index = 0;
829 return "color";
830 case LA_COL_G:
831 *r_array_index = 1;
832 return "color";
833 case LA_COL_B:
834 *r_array_index = 2;
835 return "color";
836
837 case LA_DIST:
838 return "distance";
839
840 case LA_SPOTSI:
841 return "spot_size";
842 case LA_SPOTBL:
843 return "spot_blend";
844
845 case LA_QUAD1:
846 return "linear_attenuation";
847 case LA_QUAD2:
848 return "quadratic_attenuation";
849
850 case LA_HALOINT:
851 return "halo_intensity";
852
853 default: /* for now, we assume that the others were MTex channels */
854 return mtex_adrcodes_to_paths(adrcode, r_array_index);
855 }
856
857 /* unrecognized adrcode, or not-yet-handled ones! */
858 return nullptr;
859}
860
861/* Sound Types */
862static const char *sound_adrcodes_to_paths(int adrcode, int *r_array_index)
863{
864 /* Set array index like this in-case nothing sets it correctly. */
865 *r_array_index = 0;
866
867 /* result depends on adrcode */
868 switch (adrcode) {
869 case SND_VOLUME:
870 return "volume";
871 case SND_PITCH:
872 return "pitch";
873/* XXX Joshua -- I had wrapped panning in rna,
874 * but someone commented out, calling it "unused" */
875#if 0
876 case SND_PANNING:
877 return "panning";
878#endif
879 case SND_ATTEN:
880 return "attenuation";
881 }
882
883 /* unrecognized adrcode, or not-yet-handled ones! */
884 return nullptr;
885}
886
887/* World Types */
888static const char *world_adrcodes_to_paths(int adrcode, int *r_array_index)
889{
890 /* Set array index like this in-case nothing sets it correctly. */
891 *r_array_index = 0;
892
893 /* result depends on adrcode */
894 switch (adrcode) {
895 case WO_HOR_R:
896 *r_array_index = 0;
897 return "horizon_color";
898 case WO_HOR_G:
899 *r_array_index = 1;
900 return "horizon_color";
901 case WO_HOR_B:
902 *r_array_index = 2;
903 return "horizon_color";
904 case WO_ZEN_R:
905 *r_array_index = 0;
906 return "zenith_color";
907 case WO_ZEN_G:
908 *r_array_index = 1;
909 return "zenith_color";
910 case WO_ZEN_B:
911 *r_array_index = 2;
912 return "zenith_color";
913
914 case WO_EXPOS:
915 return "exposure";
916
917 case WO_MISI:
918 return "mist.intensity";
919 case WO_MISTDI:
920 return "mist.depth";
921 case WO_MISTSTA:
922 return "mist.start";
923 case WO_MISTHI:
924 return "mist.height";
925
926 default: /* for now, we assume that the others were MTex channels */
927 return mtex_adrcodes_to_paths(adrcode, r_array_index);
928 }
929
930 return nullptr;
931}
932
933/* Particle Types */
934static const char *particle_adrcodes_to_paths(int adrcode, int *r_array_index)
935{
936 /* Set array index like this in-case nothing sets it correctly. */
937 *r_array_index = 0;
938
939 /* result depends on adrcode */
940 switch (adrcode) {
941 case PART_CLUMP:
942 return "settings.clump_factor";
943 case PART_AVE:
944 return "settings.angular_velocity_factor";
945 case PART_SIZE:
946 return "settings.particle_size";
947 case PART_DRAG:
948 return "settings.drag_factor";
949 case PART_BROWN:
950 return "settings.brownian_factor";
951 case PART_DAMP:
952 return "settings.damp_factor";
953 case PART_LENGTH:
954 return "settings.length";
955 case PART_GRAV_X:
956 *r_array_index = 0;
957 return "settings.acceleration";
958 case PART_GRAV_Y:
959 *r_array_index = 1;
960 return "settings.acceleration";
961 case PART_GRAV_Z:
962 *r_array_index = 2;
963 return "settings.acceleration";
964 case PART_KINK_AMP:
965 return "settings.kink_amplitude";
966 case PART_KINK_FREQ:
967 return "settings.kink_frequency";
968 case PART_KINK_SHAPE:
969 return "settings.kink_shape";
970 case PART_BB_TILT:
971 return "settings.billboard_tilt";
972
973/* PartDeflect needs to be sorted out properly in rna_object_force;
974 * If anyone else works on this, but is unfamiliar, these particular
975 * settings reference the particles of the system themselves
976 * being used as forces -- it will use the same rna structure
977 * as the similar object forces */
978#if 0
979 case PART_PD_FSTR:
980 if (part->pd) {
981 poin = &(part->pd->f_strength);
982 }
983 break;
984 case PART_PD_FFALL:
985 if (part->pd) {
986 poin = &(part->pd->f_power);
987 }
988 break;
989 case PART_PD_FMAXD:
990 if (part->pd) {
991 poin = &(part->pd->maxdist);
992 }
993 break;
994 case PART_PD2_FSTR:
995 if (part->pd2) {
996 poin = &(part->pd2->f_strength);
997 }
998 break;
999 case PART_PD2_FFALL:
1000 if (part->pd2) {
1001 poin = &(part->pd2->f_power);
1002 }
1003 break;
1004 case PART_PD2_FMAXD:
1005 if (part->pd2) {
1006 poin = &(part->pd2->maxdist);
1007 }
1008 break;
1009#endif
1010 }
1011
1012 return nullptr;
1013}
1014
1015/* ------- */
1016
1017/* Allocate memory for RNA-path for some property given a blocktype, adrcode,
1018 * and 'root' parts of path.
1019 *
1020 * Input:
1021 * - id - the data-block that the curve's IPO block
1022 * is attached to and/or which the new paths will start from
1023 * - blocktype, adrcode - determines setting to get
1024 * - actname, constname, seq - used to build path
1025 * Output:
1026 * - r_array_index - index in property's array (if applicable) to use
1027 * - return - the allocated path...
1028 */
1029static char *get_rna_access(ID *id,
1030 int blocktype,
1031 int adrcode,
1032 const char actname[],
1033 const char constname[],
1034 Strip *strip,
1035 int *r_array_index)
1036{
1037 DynStr *path = BLI_dynstr_new();
1038 const char *propname = nullptr;
1039 char *rpath = nullptr;
1040 char buf[512];
1041 int dummy_index = 0;
1042
1043 /* hack: if constname is set, we can only be dealing with an Constraint curve */
1044 if (constname) {
1045 blocktype = ID_CO;
1046 }
1047
1048 /* get property name based on blocktype */
1049 switch (blocktype) {
1050 case ID_OB: /* object */
1051 propname = ob_adrcodes_to_paths(adrcode, &dummy_index);
1052 break;
1053
1054 case ID_PO: /* pose channel */
1055 propname = pchan_adrcodes_to_paths(adrcode, &dummy_index);
1056 break;
1057
1058 case ID_KE: /* shapekeys */
1059 propname = shapekey_adrcodes_to_paths(id, adrcode, &dummy_index);
1060 break;
1061
1062 case ID_CO: /* constraint */
1063 propname = constraint_adrcodes_to_paths(adrcode, &dummy_index);
1064 break;
1065
1066 case ID_TE: /* texture */
1067 propname = texture_adrcodes_to_paths(adrcode, &dummy_index);
1068 break;
1069
1070 case ID_MA: /* material */
1071 propname = material_adrcodes_to_paths(adrcode, &dummy_index);
1072 break;
1073
1074 case ID_CA: /* camera */
1075 propname = camera_adrcodes_to_paths(adrcode, &dummy_index);
1076 break;
1077
1078 case ID_LA: /* light */
1079 propname = light_adrcodes_to_paths(adrcode, &dummy_index);
1080 break;
1081
1082 case ID_SO: /* sound */
1083 propname = sound_adrcodes_to_paths(adrcode, &dummy_index);
1084 break;
1085
1086 case ID_WO: /* world */
1087 propname = world_adrcodes_to_paths(adrcode, &dummy_index);
1088 break;
1089
1090 case ID_PA: /* particle */
1091 propname = particle_adrcodes_to_paths(adrcode, &dummy_index);
1092 break;
1093
1094 case ID_CU_LEGACY: /* curve */
1095 /* this used to be a 'dummy' curve which got evaluated on the fly...
1096 * now we've got real var for this!
1097 */
1098 propname = "eval_time";
1099 break;
1100
1101 /* XXX problematic block-types. */
1102 case ID_SEQ: /* sequencer strip */
1103 /* STRIP_FAC1: */
1104 switch (adrcode) {
1105 case STRIP_FAC1:
1106 propname = "effect_fader";
1107 break;
1108 case STRIP_FAC_SPEED:
1109 propname = "speed_fader";
1110 break;
1111 case STRIP_FAC_OPACITY:
1112 propname = "blend_alpha";
1113 break;
1114 }
1115 /* XXX this doesn't seem to be included anywhere in sequencer RNA... */
1116 // poin= &(seq->facf0);
1117 break;
1118
1119 /* special hacks */
1120 case -1:
1121 /* special case for rotdiff drivers... we don't need a property for this... */
1122 break;
1123
1124 /* TODO: add other block-types. */
1125 default:
1126 CLOG_WARN(&LOG, "No path for blocktype %d, adrcode %d yet", blocktype, adrcode);
1127 break;
1128 }
1129
1130 /* check if any property found
1131 * - blocktype < 0 is special case for a specific type of driver,
1132 * where we don't need a property name...
1133 */
1134 if ((propname == nullptr) && (blocktype > 0)) {
1135 /* nothing was found, so exit */
1136 if (r_array_index) {
1137 *r_array_index = 0;
1138 }
1139
1140 BLI_dynstr_free(path);
1141
1142 return nullptr;
1143 }
1144
1145 if (r_array_index) {
1146 *r_array_index = dummy_index;
1147 }
1148
1149 /* 'buf' _must_ be initialized in this block */
1150 /* append preceding bits to path */
1151 /* NOTE: strings are not escaped and they should be! */
1152 if ((actname && actname[0]) && (constname && constname[0])) {
1153 /* Constraint in Pose-Channel */
1154 char actname_esc[sizeof(bActionChannel::name) * 2];
1155 char constname_esc[sizeof(bConstraint::name) * 2];
1156 BLI_str_escape(actname_esc, actname, sizeof(actname_esc));
1157 BLI_str_escape(constname_esc, constname, sizeof(constname_esc));
1158 SNPRINTF(buf, "pose.bones[\"%s\"].constraints[\"%s\"]", actname_esc, constname_esc);
1159 }
1160 else if (actname && actname[0]) {
1161 if ((blocktype == ID_OB) && STREQ(actname, "Object")) {
1162 /* Actionified "Object" IPO's... no extra path stuff needed */
1163 buf[0] = '\0'; /* empty string */
1164 }
1165 else if ((blocktype == ID_KE) && STREQ(actname, "Shape")) {
1166 /* Actionified "Shape" IPO's -
1167 * these are forced onto object level via the action container there... */
1168 STRNCPY(buf, "data.shape_keys");
1169 }
1170 else {
1171 /* Pose-Channel */
1172 char actname_esc[sizeof(bActionChannel::name) * 2];
1173 BLI_str_escape(actname_esc, actname, sizeof(actname_esc));
1174 SNPRINTF(buf, "pose.bones[\"%s\"]", actname_esc);
1175 }
1176 }
1177 else if (constname && constname[0]) {
1178 /* Constraint in Object */
1179 char constname_esc[sizeof(bConstraint::name) * 2];
1180 BLI_str_escape(constname_esc, constname, sizeof(constname_esc));
1181 SNPRINTF(buf, "constraints[\"%s\"]", constname_esc);
1182 }
1183 else if (strip) {
1184 /* Strip names in Scene */
1185 char strip_name_esc[(sizeof(strip->name) - 2) * 2];
1186 BLI_str_escape(strip_name_esc, strip->name + 2, sizeof(strip_name_esc));
1187 SNPRINTF(buf, "sequence_editor.sequences_all[\"%s\"]", strip_name_esc);
1188 }
1189 else {
1190 buf[0] = '\0'; /* empty string */
1191 }
1192
1193 BLI_dynstr_append(path, buf);
1194
1195 /* need to add dot before property if there was anything preceding this */
1196 if (buf[0]) {
1197 BLI_dynstr_append(path, ".");
1198 }
1199
1200 /* now write name of property */
1201 BLI_dynstr_append(path, propname);
1202
1203 /* if there was no array index pointer provided, add it to the path */
1204 if (r_array_index == nullptr) {
1205 SNPRINTF(buf, "[\"%d\"]", dummy_index);
1206 BLI_dynstr_append(path, buf);
1207 }
1208
1209 /* convert to normal MEM_malloc'd string */
1210 rpath = BLI_dynstr_get_cstring(path);
1211 BLI_dynstr_free(path);
1212
1213 /* return path... */
1214 return rpath;
1215}
1216
1217/* *************************************************** */
1218/* Conversion Utilities */
1219
1220/* Convert adrcodes to driver target transform channel types */
1221static short adrcode_to_dtar_transchan(short adrcode)
1222{
1223 switch (adrcode) {
1224 case OB_LOC_X:
1225 return DTAR_TRANSCHAN_LOCX;
1226 case OB_LOC_Y:
1227 return DTAR_TRANSCHAN_LOCY;
1228 case OB_LOC_Z:
1229 return DTAR_TRANSCHAN_LOCZ;
1230
1231 case OB_ROT_X:
1232 return DTAR_TRANSCHAN_ROTX;
1233 case OB_ROT_Y:
1234 return DTAR_TRANSCHAN_ROTY;
1235 case OB_ROT_Z:
1236 return DTAR_TRANSCHAN_ROTZ;
1237
1238 case OB_SIZE_X:
1239 return DTAR_TRANSCHAN_SCALEX;
1240 case OB_SIZE_Y:
1241 return DTAR_TRANSCHAN_SCALEX;
1242 case OB_SIZE_Z:
1243 return DTAR_TRANSCHAN_SCALEX;
1244
1245 default:
1246 return 0;
1247 }
1248}
1249
1250/* Convert IpoDriver to ChannelDriver - will free the old data (i.e. the old driver) */
1252{
1253 ChannelDriver *cdriver;
1254
1255 /* allocate memory for new driver */
1256 cdriver = MEM_callocN<ChannelDriver>("ChannelDriver");
1257
1258 /* If `pydriver`, just copy data across. */
1259 if (idriver->type == IPO_DRIVER_TYPE_PYTHON) {
1260 /* PyDriver only requires the expression to be copied */
1261 /* FIXME: expression will be useless due to API changes, but at least not totally lost */
1262 cdriver->type = DRIVER_TYPE_PYTHON;
1263 if (idriver->name[0]) {
1264 STRNCPY(cdriver->expression, idriver->name);
1265 }
1266 }
1267 else {
1268 DriverVar *dvar = nullptr;
1269 DriverTarget *dtar = nullptr;
1270
1271 /* this should be ok for all types here... */
1272 cdriver->type = DRIVER_TYPE_AVERAGE;
1273
1274 /* What to store depends on the `blocktype` - object or pose-channel. */
1275 if (idriver->blocktype == ID_AR) { /* PoseChannel */
1276 if (idriver->adrcode == OB_ROT_DIFF) {
1277 /* Rotational Difference requires a special type of variable */
1278 dvar = driver_add_new_variable(cdriver);
1280
1281 /* first bone target */
1282 dtar = &dvar->targets[0];
1283 dtar->id = (ID *)idriver->ob;
1284 dtar->idtype = ID_OB;
1285 if (idriver->name[0]) {
1286 STRNCPY(dtar->pchan_name, idriver->name);
1287 }
1288
1289 /* second bone target (name was stored in same var as the first one) */
1290 dtar = &dvar->targets[1];
1291 dtar->id = (ID *)idriver->ob;
1292 dtar->idtype = ID_OB;
1293 if (idriver->name[0]) { /* XXX: for safety. */
1294 STRNCPY(dtar->pchan_name, idriver->name + DRIVER_NAME_OFFS);
1295 }
1296 }
1297 else {
1298 /* only a single variable, of type 'transform channel' */
1299 dvar = driver_add_new_variable(cdriver);
1301
1302 /* only requires a single target */
1303 dtar = &dvar->targets[0];
1304 dtar->id = (ID *)idriver->ob;
1305 dtar->idtype = ID_OB;
1306 if (idriver->name[0]) {
1307 STRNCPY(dtar->pchan_name, idriver->name);
1308 }
1310 dtar->flag |= DTAR_FLAG_LOCALSPACE; /* old drivers took local space */
1311 }
1312 }
1313 else { /* Object */
1314 /* only a single variable, of type 'transform channel' */
1315 dvar = driver_add_new_variable(cdriver);
1317
1318 /* only requires single target */
1319 dtar = &dvar->targets[0];
1320 dtar->id = (ID *)idriver->ob;
1321 dtar->idtype = ID_OB;
1323 }
1324 }
1325
1326 /* return the new one */
1327 return cdriver;
1328}
1329
1330/* Add F-Curve to the correct list
1331 * - grpname is needed to be used as group name where relevant, and is usually derived from actname
1332 */
1334 ListBase *groups, ListBase *list, FCurve *fcu, char *grpname, int muteipo)
1335{
1336 /* If we're adding to an action, we will have groups to write to... */
1337 if (groups && grpname) {
1338 /* wrap the pointers given into a dummy action that we pass to the API func
1339 * and extract the resultant lists...
1340 */
1341 bAction tmp_act = {};
1342 bActionGroup *agrp = nullptr;
1343
1344 /* init the temp action */
1345 tmp_act.groups.first = groups->first;
1346 tmp_act.groups.last = groups->last;
1347 tmp_act.curves.first = list->first;
1348 tmp_act.curves.last = list->last;
1349 /* XXX: The other vars don't need to be filled in. */
1350
1351 /* get the group to use */
1352 agrp = BKE_action_group_find_name(&tmp_act, grpname);
1353 /* no matching group, so add one */
1354 if (agrp == nullptr) {
1355 /* Add a new group, and make it active */
1356 agrp = MEM_callocN<bActionGroup>("bActionGroup");
1357
1358 agrp->flag = AGRP_SELECTED;
1359 if (muteipo) {
1360 agrp->flag |= AGRP_MUTED;
1361 }
1362
1363 STRNCPY(agrp->name, grpname);
1364
1365 BLI_addtail(&tmp_act.groups, agrp);
1366 BLI_uniquename(&tmp_act.groups,
1367 agrp,
1368 DATA_("Group"),
1369 '.',
1370 offsetof(bActionGroup, name),
1371 sizeof(agrp->name));
1372 }
1373
1374 /* add F-Curve to group */
1375 /* WARNING: this func should only need to look at the stuff we initialized,
1376 * if not, things may crash. */
1377 action_groups_add_channel(&tmp_act, agrp, fcu);
1378
1379 if (agrp->flag & AGRP_MUTED) { /* flush down */
1380 fcu->flag |= FCURVE_MUTED;
1381 }
1382
1383 /* set the output lists based on the ones in the temp action */
1384 groups->first = tmp_act.groups.first;
1385 groups->last = tmp_act.groups.last;
1386 list->first = tmp_act.curves.first;
1387 list->last = tmp_act.curves.last;
1388 }
1389 else {
1390 /* simply add the F-Curve to the end of the given list */
1391 BLI_addtail(list, fcu);
1392 }
1393}
1394
1407static void icu_to_fcurves(ID *id,
1408 ListBase *groups,
1409 ListBase *list,
1410 IpoCurve *icu,
1411 char *actname,
1412 char *constname,
1413 Strip *strip,
1414 int muteipo)
1415{
1416 AdrBit2Path *abp;
1417 FCurve *fcu;
1418 int totbits;
1419
1420 /* allocate memory for a new F-Curve */
1421 fcu = BKE_fcurve_create();
1422
1423 /* convert driver */
1424 if (icu->driver) {
1425 fcu->driver = idriver_to_cdriver(icu->driver);
1426 }
1427
1428 /* copy flags */
1429 if (icu->flag & IPO_VISIBLE) {
1430 fcu->flag |= FCURVE_VISIBLE;
1431 }
1432 if (icu->flag & IPO_SELECT) {
1433 fcu->flag |= FCURVE_SELECTED;
1434 }
1435 if (icu->flag & IPO_ACTIVE) {
1436 fcu->flag |= FCURVE_ACTIVE;
1437 }
1438 if (icu->flag & IPO_MUTE) {
1439 fcu->flag |= FCURVE_MUTED;
1440 }
1441 if (icu->flag & IPO_PROTECT) {
1442 fcu->flag |= FCURVE_PROTECTED;
1443 }
1444
1445 /* set extrapolation */
1446 switch (icu->extrap) {
1447 case IPO_HORIZ: /* constant extrapolation */
1448 case IPO_DIR: /* linear extrapolation */
1449 {
1450 /* just copy, as the new defines match the old ones... */
1451 fcu->extend = icu->extrap;
1452 break;
1453 }
1454 case IPO_CYCL: /* cyclic extrapolation */
1455 case IPO_CYCLX: /* cyclic extrapolation + offset */
1456 {
1457 /* Add a new FModifier (Cyclic) instead of setting extend value
1458 * as that's the new equivalent of that option.
1459 */
1461 FMod_Cycles *data = (FMod_Cycles *)fcm->data;
1462
1463 /* if 'offset' one is in use, set appropriate settings */
1464 if (icu->extrap == IPO_CYCLX) {
1465 data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC_OFFSET;
1466 }
1467 else {
1468 data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC;
1469 }
1470 break;
1471 }
1472 }
1473
1474 /* -------- */
1475
1476 /* get adrcode <-> bitflags mapping to handle nasty bitflag curves? */
1477 abp = adrcode_bitmaps_to_paths(icu->blocktype, icu->adrcode, &totbits);
1478 if (abp && totbits) {
1479 FCurve *fcurve;
1480 int b;
1481
1482 if (G.debug & G_DEBUG) {
1483 printf("\tconvert bitflag ipocurve, totbits = %d\n", totbits);
1484 }
1485
1486 /* add the 'only int values' flag */
1488
1489 /* for each bit we have to remap + check for:
1490 * 1) we need to make copy the existing F-Curve data (fcu -> fcurve),
1491 * except for the last one which will use the original
1492 * 2) copy the relevant path info across
1493 * 3) filter the keyframes for the flag of interest
1494 */
1495 for (b = 0; b < totbits; b++, abp++) {
1496 uint i = 0;
1497
1498 /* make a copy of existing base-data if not the last curve */
1499 if (b < (totbits - 1)) {
1500 fcurve = BKE_fcurve_copy(fcu);
1501 }
1502 else {
1503 fcurve = fcu;
1504 }
1505
1506 /* set path */
1507 fcurve->rna_path = BLI_strdup(abp->path);
1508 fcurve->array_index = abp->array_index;
1509
1510 /* Convert keyframes:
1511 * - Beztriples and bpoints are mutually exclusive,
1512 * so we won't have both at the same time.
1513 * - Beztriples are more likely to be encountered as they are keyframes
1514 * (the other type wasn't used yet).
1515 */
1516 fcurve->totvert = icu->totvert;
1517
1518 if (icu->bezt) {
1519 BezTriple *dst, *src;
1520
1521 /* allocate new array for keyframes/beztriples */
1522 fcurve->bezt = MEM_calloc_arrayN<BezTriple>(fcurve->totvert, "BezTriples");
1523
1524 /* loop through copying all BezTriples individually, as we need to modify a few things */
1525 for (dst = fcurve->bezt, src = icu->bezt, i = 0; i < fcurve->totvert; i++, dst++, src++) {
1526 /* firstly, copy BezTriple data */
1527 *dst = *src;
1528
1529 /* interpolation can only be constant... */
1530 dst->ipo = BEZT_IPO_CONST;
1531
1532 /* 'hide' flag is now used for keytype - only 'keyframes' existed before */
1534
1535 /* auto-handles - per curve to per handle */
1536 if (icu->flag & IPO_AUTO_HORIZ) {
1537 if (dst->h1 == HD_AUTO) {
1538 dst->h1 = HD_AUTO_ANIM;
1539 }
1540 if (dst->h2 == HD_AUTO) {
1541 dst->h2 = HD_AUTO_ANIM;
1542 }
1543 }
1544
1545 /* correct values, by checking if the flag of interest is set */
1546 if (int(dst->vec[1][1]) & (abp->bit)) {
1547 dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 1.0f;
1548 }
1549 else {
1550 dst->vec[0][1] = dst->vec[1][1] = dst->vec[2][1] = 0.0f;
1551 }
1552 }
1553 }
1554 else if (icu->bp) {
1555 /* TODO: need to convert from BPoint type to the more compact FPoint type...
1556 * but not priority, since no data used this. */
1557 // BPoint *bp;
1558 // FPoint *fpt;
1559 }
1560
1561 /* add new F-Curve to list */
1562 fcurve_add_to_list(groups, list, fcurve, actname, muteipo);
1563 }
1564 }
1565 else {
1566 uint i = 0;
1567
1568 /* get rna-path
1569 * - we will need to set the 'disabled' flag if no path is able to be made (for now)
1570 */
1571 fcu->rna_path = get_rna_access(
1572 id, icu->blocktype, icu->adrcode, actname, constname, strip, &fcu->array_index);
1573 if (fcu->rna_path == nullptr) {
1574 fcu->flag |= FCURVE_DISABLED;
1575 }
1576
1577 /* Convert keyframes:
1578 * - Beztriples and bpoints are mutually exclusive, so we won't have both at the same time.
1579 * - Beztriples are more likely to be encountered as they are keyframes
1580 * (the other type wasn't used yet).
1581 */
1582 fcu->totvert = icu->totvert;
1583
1584 if (icu->bezt) {
1585 BezTriple *dst, *src;
1586
1587 /* allocate new array for keyframes/beztriples */
1588 fcu->bezt = MEM_calloc_arrayN<BezTriple>(fcu->totvert, "BezTriples");
1589
1590 /* loop through copying all BezTriples individually, as we need to modify a few things */
1591 for (dst = fcu->bezt, src = icu->bezt, i = 0; i < fcu->totvert; i++, dst++, src++) {
1592 /* firstly, copy BezTriple data */
1593 *dst = *src;
1594
1595 /* now copy interpolation from curve (if not already set) */
1596 if (icu->ipo != IPO_MIXED) {
1597 dst->ipo = icu->ipo;
1598 }
1599
1600 /* 'hide' flag is now used for keytype - only 'keyframes' existed before */
1602
1603 /* auto-handles - per curve to per handle */
1604 if (icu->flag & IPO_AUTO_HORIZ) {
1605 if (dst->h1 == HD_AUTO) {
1606 dst->h1 = HD_AUTO_ANIM;
1607 }
1608 if (dst->h2 == HD_AUTO) {
1609 dst->h2 = HD_AUTO_ANIM;
1610 }
1611 }
1612
1613 /* correct values for euler rotation curves
1614 * - they were degrees/10
1615 * - we need radians for RNA to do the right thing
1616 */
1617 if (((icu->blocktype == ID_OB) && ELEM(icu->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) ||
1618 ((icu->blocktype == ID_PO) && ELEM(icu->adrcode, AC_EUL_X, AC_EUL_Y, AC_EUL_Z)))
1619 {
1620 const float fac = float(M_PI) / 18.0f; /* `10.0f * M_PI/180.0f`. */
1621
1622 dst->vec[0][1] *= fac;
1623 dst->vec[1][1] *= fac;
1624 dst->vec[2][1] *= fac;
1625 }
1626
1627 /* correct values for path speed curves
1628 * - their values were 0-1
1629 * - we now need as 'frames'
1630 */
1631 if ((id) && (icu->blocktype == GS(id->name)) && (GS(id->name) == ID_CU_LEGACY) &&
1632 (fcu->rna_path && STREQ(fcu->rna_path, "eval_time")))
1633 {
1634 const Curve *cu = (const Curve *)id;
1635
1636 dst->vec[0][1] *= cu->pathlen;
1637 dst->vec[1][1] *= cu->pathlen;
1638 dst->vec[2][1] *= cu->pathlen;
1639 }
1640
1641 /* correct times for rotation drivers
1642 * - need to go from degrees to radians...
1643 * - there's only really 1 target to worry about
1644 * - were also degrees/10
1645 */
1646 if (fcu->driver && fcu->driver->variables.first) {
1647 const DriverVar *dvar = static_cast<const DriverVar *>(fcu->driver->variables.first);
1648 const DriverTarget *dtar = &dvar->targets[0];
1649
1651 {
1652 const float fac = float(M_PI) / 18.0f;
1653
1654 dst->vec[0][0] *= fac;
1655 dst->vec[1][0] *= fac;
1656 dst->vec[2][0] *= fac;
1657 }
1658 }
1659
1660 /* correct values for sequencer curves, that were not locked to frame */
1661 if (strip && (strip->flag & SEQ_IPO_FRAME_LOCKED) == 0) {
1662 const float mul = (strip->enddisp - strip->startdisp) / 100.0f;
1663 const float offset = strip->startdisp;
1664
1665 dst->vec[0][0] *= mul;
1666 dst->vec[0][0] += offset;
1667
1668 dst->vec[1][0] *= mul;
1669 dst->vec[1][0] += offset;
1670
1671 dst->vec[2][0] *= mul;
1672 dst->vec[2][0] += offset;
1673 }
1674 }
1675 }
1676 else if (icu->bp) {
1677 /* TODO: need to convert from BPoint type to the more compact FPoint type...
1678 * but not priority, since no data used this */
1679 // BPoint *bp;
1680 // FPoint *fpt;
1681 }
1682
1683 /* add new F-Curve to list */
1684 fcurve_add_to_list(groups, list, fcu, actname, muteipo);
1685 }
1686}
1687
1688/* ------------------------- */
1689
1708static void ipo_to_animato(ID *id,
1709 Ipo *ipo,
1710 char actname[],
1711 char constname[],
1712 Strip *strip,
1713 ListBase /* bActionGroup */ *animgroups,
1714 ListBase /* FCurve */ *anim,
1715 ListBase /* FCurve */ *drivers)
1716{
1717 IpoCurve *icu;
1718
1719 /* sanity check */
1720 if (ELEM(nullptr, ipo, anim, drivers)) {
1721 return;
1722 }
1723
1724 if (G.debug & G_DEBUG) {
1725 printf("ipo_to_animato\n");
1726 }
1727
1728 /* validate actname and constname
1729 * - clear actname if it was one of the generic <builtin> ones (i.e. 'Object', or 'Shapes')
1730 * - actname can then be used to assign F-Curves in Action to Action Groups
1731 * (i.e. thus keeping the benefits that used to be provided by Action Channels for grouping
1732 * F-Curves for bones). This may be added later... for now let's just dump without them...
1733 */
1734 if (actname) {
1735 if ((ipo->blocktype == ID_OB) && STREQ(actname, "Object")) {
1736 actname = nullptr;
1737 }
1738 else if ((ipo->blocktype == ID_OB) && STREQ(actname, "Shape")) {
1739 actname = nullptr;
1740 }
1741 }
1742
1743 /* loop over IPO-Curves, freeing as we progress */
1744 LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
1745 /* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves),
1746 * we figure out the best place to put the channel,
1747 * then tell the curve-converter to just dump there. */
1748 if (icu->driver) {
1749 /* Blender 2.4x allowed empty drivers,
1750 * but we don't now, since they cause more trouble than they're worth. */
1751 if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) {
1752 icu_to_fcurves(id, nullptr, drivers, icu, actname, constname, strip, ipo->muteipo);
1753 }
1754 else {
1755 MEM_freeN(icu->driver);
1756 icu->driver = nullptr;
1757 }
1758 }
1759 else {
1760 icu_to_fcurves(id, animgroups, anim, icu, actname, constname, strip, ipo->muteipo);
1761 }
1762 }
1763
1764 /* if this IPO block doesn't have any users after this one, free... */
1765 id_us_min(&ipo->id);
1766 if (ID_REAL_USERS(ipo) <= 0) {
1767 IpoCurve *icn;
1768
1769 for (icu = static_cast<IpoCurve *>(ipo->curve.first); icu; icu = icn) {
1770 icn = icu->next;
1771
1772 /* free driver */
1773 if (icu->driver) {
1774 MEM_freeN(icu->driver);
1775 }
1776
1777 /* free old data of curve now that it's no longer needed for converting any more curves */
1778 if (icu->bezt) {
1779 MEM_freeN(icu->bezt);
1780 }
1781 if (icu->bp) {
1782 MEM_freeN(icu->bezt);
1783 }
1784
1785 /* free this IPO-Curve */
1786 BLI_freelinkN(&ipo->curve, icu);
1787 }
1788 }
1789}
1790
1807 ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
1808{
1809 const bool is_pre_animato_action = !BLI_listbase_is_empty(&act->chanbase);
1810 BLI_assert_msg(is_pre_animato_action, "Action is not pre-Animato.");
1811 if (!is_pre_animato_action) {
1812 return;
1813 }
1814
1815 /* get rid of all Action Groups */
1816 /* XXX this is risky if there's some old + some new data in the Action... */
1817 if (act->groups.first) {
1818 BLI_freelistN(&act->groups);
1819 }
1820
1821 /* loop through Action-Channels, converting data, freeing as we go */
1822 LISTBASE_FOREACH_MUTABLE (bActionChannel *, achan, &act->chanbase) {
1823 /* convert Action Channel's IPO data */
1824 if (achan->ipo) {
1825 ipo_to_animato(id, achan->ipo, achan->name, nullptr, nullptr, groups, curves, drivers);
1826 id_us_min(&achan->ipo->id);
1827 achan->ipo = nullptr;
1828 }
1829
1830 /* convert constraint channel IPO-data */
1831 LISTBASE_FOREACH_MUTABLE (bConstraintChannel *, conchan, &achan->constraintChannels) {
1832 /* convert Constraint Channel's IPO data */
1833 if (conchan->ipo) {
1835 id, conchan->ipo, achan->name, conchan->name, nullptr, groups, curves, drivers);
1836 id_us_min(&conchan->ipo->id);
1837 conchan->ipo = nullptr;
1838 }
1839
1840 /* free Constraint Channel */
1841 BLI_freelinkN(&achan->constraintChannels, conchan);
1842 }
1843
1844 /* free Action Channel */
1845 BLI_freelinkN(&act->chanbase, achan);
1846 }
1847}
1848
1864 ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
1865{
1866 /* Already converted to the most modern kind of action, so no need to
1867 * convert. */
1869 return;
1870 }
1871
1872 /* If there are Action Channels, indicating a pre-Animato action, then convert
1873 * to Animato data. Note that pre-Animato actions may include drivers! */
1874 const bool is_pre_animato_action = !BLI_listbase_is_empty(&act->chanbase);
1875 if (is_pre_animato_action) {
1876 convert_pre_animato_action_to_animato_action_in_place(id, act, groups, curves, drivers);
1877 }
1878
1879 /* If there is an animated ID, tag it so that its Action usage also will get converted. */
1880 if (id) {
1882 }
1883
1884 /* Convert to layered action. */
1886}
1887
1888/* ------------------------- */
1889
1890/* Convert IPO-block (i.e. all its IpoCurves) for some ID to the new system
1891 * This assumes that AnimData has been added already. Separation of drivers
1892 * from animation data is accomplished here too...
1893 */
1895 Main *bmain, ID *id, Ipo *ipo, char actname[], char constname[], Strip *strip)
1896{
1897 AnimData *adt = BKE_animdata_from_id(id);
1898 ListBase anim = {nullptr, nullptr};
1899 ListBase drivers = {nullptr, nullptr};
1900
1901 /* sanity check */
1902 if (ELEM(nullptr, id, ipo)) {
1903 return;
1904 }
1905 if (adt == nullptr) {
1906 CLOG_ERROR(&LOG, "adt invalid");
1907 return;
1908 }
1909
1910 if (G.debug & G_DEBUG) {
1911 printf("ipo to animdata - ID:%s, IPO:%s, actname:%s constname:%s stripname:%s curves:%d\n",
1912 id->name + 2,
1913 ipo->id.name + 2,
1914 (actname) ? actname : "<None>",
1915 (constname) ? constname : "<None>",
1916 (strip) ? (strip->name + 2) : "<None>",
1917 BLI_listbase_count(&ipo->curve));
1918 }
1919
1920 /* Convert curves to animato system
1921 * (separated into separate lists of F-Curves for animation and drivers),
1922 * and the try to put these lists in the right places, but do not free the lists here. */
1923 /* XXX there shouldn't be any need for the groups, so don't supply pointer for that now... */
1924 ipo_to_animato(id, ipo, actname, constname, strip, nullptr, &anim, &drivers);
1925
1926 /* deal with animation first */
1927 if (anim.first) {
1928 if (G.debug & G_DEBUG) {
1929 printf("\thas anim\n");
1930 }
1931 /* try to get action */
1932 if (adt->action == nullptr) {
1933 char nameBuf[MAX_ID_NAME];
1934
1935 SNPRINTF(nameBuf, "CDA:%s", ipo->id.name + 2);
1936
1937 bAction *action = BKE_action_add(bmain, nameBuf);
1938 id_us_min(&action->id);
1939 const bool assign_ok = animrig::assign_action(action, {*id, *adt});
1940 BLI_assert_msg(assign_ok, "Expecting the assignment of a new Action to always work");
1941 UNUSED_VARS_NDEBUG(assign_ok);
1942
1943 if (G.debug & G_DEBUG) {
1944 printf("\t\tadded new action - '%s'\n", nameBuf);
1945 }
1946 }
1947
1948 /* Add F-Curves to action, creating an Animato action. */
1949 BLI_movelisttolist(&adt->action->curves, &anim);
1950
1951 /* Upgrade Animato action to a layered action. */
1954 }
1955
1956 /* deal with drivers */
1957 if (drivers.first) {
1958 if (G.debug & G_DEBUG) {
1959 printf("\thas drivers\n");
1960 }
1961 /* add drivers to end of driver stack */
1962 BLI_movelisttolist(&adt->drivers, &drivers);
1963 }
1964}
1965
1966/* Convert Action-block to new system
1967 * NOTE: we need to be careful here, as same data-structs are used for new system too!
1968 */
1969static void action_to_animdata(ID *id, bAction *act)
1970{
1971 AnimData *adt = BKE_animdata_from_id(id);
1972
1973 /* only continue if there are Action Channels (indicating unconverted data) */
1974 if (ELEM(nullptr, adt, act->chanbase.first)) {
1975 return;
1976 }
1977
1978 /* check if we need to set this Action as the AnimData's action */
1979 if (adt->action == nullptr) {
1980 /* set this Action as AnimData's Action */
1981 if (G.debug & G_DEBUG) {
1982 printf("act_to_adt - set adt action to act\n");
1983 }
1984 const bool assign_ok = animrig::assign_action(act, {*id, *adt});
1985 BLI_assert_msg(assign_ok, "Expecting the assignment of a just-converted Action to work");
1986 UNUSED_VARS_NDEBUG(assign_ok);
1987 }
1988
1989 /* convert Action data */
1990 ensure_action_is_layered(id, act, &adt->action->groups, &adt->action->curves, &adt->drivers);
1991}
1992
1993/* ------------------------- */
1994
1995/* TODO:
1996 * - NLA group duplicators info
1997 * - NLA curve/stride modifiers... */
1998
1999/* Convert NLA-Strip to new system */
2000static void nlastrips_to_animdata(ID *id, ListBase *strips)
2001{
2002 AnimData *adt = BKE_animdata_from_id(id);
2003 NlaTrack *nlt = nullptr;
2004 NlaStrip *strip;
2005 bActionStrip *as, *asn;
2006
2007 /* for each one of the original strips, convert to a new strip and free the old... */
2008 for (as = static_cast<bActionStrip *>(strips->first); as; as = asn) {
2009 asn = as->next;
2010
2011 /* this old strip is only worth something if it had an action... */
2012 if (as->act) {
2013 /* convert Action data (if not yet converted), storing the results in the same Action */
2014 ensure_action_is_layered(id, as->act, &as->act->groups, &as->act->curves, &adt->drivers);
2015
2016 /* Create a new-style NLA-strip which references this Action,
2017 * then copy over relevant settings. */
2018 {
2019 /* init a new strip, and assign the action to it
2020 * - no need to muck around with the user-counts, since this is just
2021 * passing over the ref to the new owner, not creating an additional ref
2022 */
2023 strip = MEM_callocN<NlaStrip>("NlaStrip");
2024 strip->act = as->act;
2025
2026 /* endpoints */
2027 strip->start = as->start;
2028 strip->end = as->end;
2029 strip->actstart = as->actstart;
2030 strip->actend = as->actend;
2031
2032 /* action reuse */
2033 strip->repeat = as->repeat;
2034 strip->scale = as->scale;
2035 if (as->flag & ACTSTRIP_LOCK_ACTION) {
2037 }
2038
2039 /* blending */
2040 strip->blendin = as->blendin;
2041 strip->blendout = as->blendout;
2042 strip->blendmode = (as->mode == ACTSTRIPMODE_ADD) ? NLASTRIP_MODE_ADD :
2044 if (as->flag & ACTSTRIP_AUTO_BLENDS) {
2046 }
2047
2048 /* assorted setting flags */
2049 if (as->flag & ACTSTRIP_SELECT) {
2050 strip->flag |= NLASTRIP_FLAG_SELECT;
2051 }
2052 if (as->flag & ACTSTRIP_ACTIVE) {
2053 strip->flag |= NLASTRIP_FLAG_ACTIVE;
2054 }
2055
2056 if (as->flag & ACTSTRIP_MUTE) {
2057 strip->flag |= NLASTRIP_FLAG_MUTED;
2058 }
2059 if (as->flag & ACTSTRIP_REVERSE) {
2060 strip->flag |= NLASTRIP_FLAG_REVERSE;
2061 }
2062
2063 /* by default, we now always extrapolate, while in the past this was optional */
2064 if ((as->flag & ACTSTRIP_HOLDLASTFRAME) == 0) {
2066 }
2067 }
2068
2069 /* Try to add this strip to the current NLA-Track
2070 * (i.e. the 'last' one on the stack at the moment). */
2071 if (BKE_nlatrack_add_strip(nlt, strip, false) == 0) {
2072 /* trying to add to the current failed (no space),
2073 * so add a new track to the stack, and add to that...
2074 */
2075 nlt = BKE_nlatrack_new_tail(&adt->nla_tracks, false);
2077 BKE_nlatrack_add_strip(nlt, strip, false);
2078 }
2079
2080 /* ensure that strip has a name */
2081 BKE_nlastrip_validate_name(adt, strip);
2082 }
2083
2084 /* modifiers */
2085 /* FIXME: for now, we just free them... */
2086 if (as->modifiers.first) {
2088 }
2089
2090 /* free the old strip */
2091 BLI_freelinkN(strips, as);
2092 }
2093}
2094
2100
2101static bool strip_convert_callback(Strip *strip, void *userdata)
2102{
2103 IpoCurve *icu = static_cast<IpoCurve *>((strip->ipo) ? strip->ipo->curve.first : nullptr);
2104 short adrcode = STRIP_FAC1;
2105
2106 if (G.debug & G_DEBUG) {
2107 printf("\tconverting sequence strip %s\n", strip->name + 2);
2108 }
2109
2110 if (ELEM(nullptr, strip->ipo, icu)) {
2112 return true;
2113 }
2114
2115 /* Patch `adrcode`, so that we can map to different DNA variables later (semi-hack (tm)). */
2116 switch (strip->type) {
2117 case STRIP_TYPE_IMAGE:
2118 case STRIP_TYPE_META:
2119 case STRIP_TYPE_SCENE:
2120 case STRIP_TYPE_MOVIE:
2121 case STRIP_TYPE_COLOR:
2122 adrcode = STRIP_FAC_OPACITY;
2123 break;
2124 case STRIP_TYPE_SPEED:
2125 adrcode = STRIP_FAC_SPEED;
2126 break;
2127 }
2128 icu->adrcode = adrcode;
2129
2130 Seq_callback_data *cd = (Seq_callback_data *)userdata;
2131
2132 /* convert IPO */
2133 ipo_to_animdata(cd->bmain, (ID *)cd->scene, strip->ipo, nullptr, nullptr, strip);
2134
2136 cd->adt->action->idroot = ID_SCE; /* scene-rooted */
2137 }
2138
2139 id_us_min(&strip->ipo->id);
2140 strip->ipo = nullptr;
2141 return true;
2142}
2143
2144/* *************************************************** */
2145/* External API - Only Called from do_versions() */
2146
2148{
2150
2151 ListBase drivers = {nullptr, nullptr};
2152 ID *id;
2153
2154 if (bmain == nullptr) {
2155 CLOG_ERROR(&LOG, "Argh! Main is nullptr");
2156 return;
2157 }
2158
2159 /* Only convert if the bmain version is old enough.
2160 *
2161 * Note that the mixing of pre-2.50 and post-2.50 animation data is not supported, and so there
2162 * is no need to check for the version of library blend files.
2163 *
2164 * See the check in #BKE_blendfile_link(), that actively warns users that their animation data
2165 * will not be converted when linking to a pre-2.50 blend file.
2166 *
2167 * But even when the main file is newer, it could still link in pre-2.50 Actions, and those need
2168 * to be converted in this function as well.
2169 */
2170 if (bmain->versionfile >= 250) {
2171 bool shown_info = false;
2172
2173 LISTBASE_FOREACH (ID *, id, &bmain->actions) {
2174 bAction *action = reinterpret_cast<bAction *>(id);
2175
2176 const bool is_pre_animato_action = !BLI_listbase_is_empty(&action->chanbase);
2177 if (!is_pre_animato_action) {
2178 continue;
2179 }
2180
2181 if (G.debug & G_DEBUG) {
2182 if (!shown_info) {
2183 printf("INFO: Converting IPO Action to modern animation data types...\n");
2184 shown_info = true;
2185 }
2186
2187 printf("\tconverting action %s\n", id->name + 2);
2188 }
2189
2190 /* This Action will be object-only. */
2191 action->idroot = ID_OB;
2192
2193 ensure_action_is_layered(nullptr, action, &action->groups, &action->curves, &drivers);
2194 }
2195 return;
2196 }
2197
2198 if (G.debug & G_DEBUG) {
2199 printf("INFO: Converting IPO to modern animation data types...\n");
2200 }
2201
2202 /* ----------- Animation Attached to Data -------------- */
2203
2204 /* objects */
2205 for (id = static_cast<ID *>(bmain->objects.first); id; id = static_cast<ID *>(id->next)) {
2206 Object *ob = (Object *)id;
2207 bConstraintChannel *conchan, *conchann;
2208
2209 if (G.debug & G_DEBUG) {
2210 printf("\tconverting ob %s\n", id->name + 2);
2211 }
2212
2213 /* check if object has any animation data */
2214 if (ob->nlastrips.first) {
2215 /* Add AnimData block */
2217
2218 /* IPO first to take into any non-NLA'd Object Animation */
2219 if (ob->ipo) {
2220 ipo_to_animdata(bmain, id, ob->ipo, nullptr, nullptr, nullptr);
2221 /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */
2222 ob->ipo = nullptr;
2223 }
2224
2225 /* Action is skipped since it'll be used by some strip in the NLA anyway,
2226 * causing errors with evaluation in the new evaluation pipeline
2227 */
2228 if (ob->action) {
2229 id_us_min(&ob->action->id);
2230 ob->action = nullptr;
2231 }
2232
2233 /* finally NLA */
2234 nlastrips_to_animdata(id, &ob->nlastrips);
2235 }
2236 else if ((ob->ipo) || (ob->action)) {
2238
2239 /* Action first - so that Action name get conserved */
2240 if (ob->action) {
2241 action_to_animdata(id, ob->action);
2242
2243 id_us_min(&ob->action->id);
2244 ob->action = nullptr;
2245 }
2246
2247 /* IPO second... */
2248 if (ob->ipo) {
2249 ipo_to_animdata(bmain, id, ob->ipo, nullptr, nullptr, nullptr);
2250 /* No need to id_us_min ipo ID here, ipo_to_animdata already does it. */
2251 ob->ipo = nullptr;
2252 }
2253 }
2254
2255 /* check PoseChannels for constraints with local data */
2256 if (ob->pose) {
2257 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
2258 LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
2259 /* if constraint has its own IPO, convert add these to Object
2260 * (NOTE: they're most likely to be drivers too)
2261 */
2262 if (con->ipo) {
2263 /* Verify if there's AnimData block */
2265
2266 /* although this was the constraint's local IPO, we still need to provide pchan + con
2267 * so that drivers can be added properly...
2268 */
2269 ipo_to_animdata(bmain, id, con->ipo, pchan->name, con->name, nullptr);
2270 id_us_min(&con->ipo->id);
2271 con->ipo = nullptr;
2272 }
2273 }
2274 }
2275 }
2276
2277 /* check constraints for local IPO's */
2279 /* if constraint has its own IPO, convert add these to Object
2280 * (NOTE: they're most likely to be drivers too)
2281 */
2282 if (con->ipo) {
2283 /* Verify if there's AnimData block, just in case */
2285
2286 /* although this was the constraint's local IPO, we still need to provide con
2287 * so that drivers can be added properly...
2288 */
2289 ipo_to_animdata(bmain, id, con->ipo, nullptr, con->name, nullptr);
2290 id_us_min(&con->ipo->id);
2291 con->ipo = nullptr;
2292 }
2293
2294 /* check for Action Constraint */
2295 /* XXX do we really want to do this here? */
2296 }
2297
2298 /* check constraint channels - we need to remove them anyway... */
2299 if (ob->constraintChannels.first) {
2300 for (conchan = static_cast<bConstraintChannel *>(ob->constraintChannels.first); conchan;
2301 conchan = conchann)
2302 {
2303 /* get pointer to next Constraint Channel */
2304 conchann = conchan->next;
2305
2306 /* convert Constraint Channel's IPO data */
2307 if (conchan->ipo) {
2308 /* Verify if there's AnimData block */
2310
2311 ipo_to_animdata(bmain, id, conchan->ipo, nullptr, conchan->name, nullptr);
2312 id_us_min(&conchan->ipo->id);
2313 conchan->ipo = nullptr;
2314 }
2315
2316 /* free Constraint Channel */
2317 BLI_freelinkN(&ob->constraintChannels, conchan);
2318 }
2319 }
2320
2321 /* object's action will always be object-rooted */
2322 {
2323 AnimData *adt = BKE_animdata_from_id(id);
2324 if (adt && adt->action && !action_is_layered(*adt->action)) {
2325 adt->action->idroot = ID_OB;
2326 }
2327 }
2328 }
2329
2330 /* shapekeys */
2331 for (id = static_cast<ID *>(bmain->shapekeys.first); id; id = static_cast<ID *>(id->next)) {
2332 Key *key = (Key *)id;
2333
2334 if (G.debug & G_DEBUG) {
2335 printf("\tconverting key %s\n", id->name + 2);
2336 }
2337
2338 /* we're only interested in the IPO
2339 * NOTE: for later, it might be good to port these over to Object instead, as many of these
2340 * are likely to be drivers, but it's hard to trace that from here, so move this to Ob loop?
2341 */
2342 if (key->ipo) {
2343 /* Add AnimData block */
2345
2346 /* Convert Shape-key data... */
2347 ipo_to_animdata(bmain, id, key->ipo, nullptr, nullptr, nullptr);
2348
2349 if (adt->action && !action_is_layered(*adt->action)) {
2350 adt->action->idroot = key->ipo->blocktype;
2351 }
2352
2353 id_us_min(&key->ipo->id);
2354 key->ipo = nullptr;
2355 }
2356 }
2357
2358 /* materials */
2359 for (id = static_cast<ID *>(bmain->materials.first); id; id = static_cast<ID *>(id->next)) {
2360 Material *ma = (Material *)id;
2361
2362 if (G.debug & G_DEBUG) {
2363 printf("\tconverting material %s\n", id->name + 2);
2364 }
2365
2366 /* we're only interested in the IPO */
2367 if (ma->ipo) {
2368 /* Add AnimData block */
2370
2371 /* Convert Material data... */
2372 ipo_to_animdata(bmain, id, ma->ipo, nullptr, nullptr, nullptr);
2373
2374 if (adt->action && !action_is_layered(*adt->action)) {
2375 adt->action->idroot = ma->ipo->blocktype;
2376 }
2377
2378 id_us_min(&ma->ipo->id);
2379 ma->ipo = nullptr;
2380 }
2381 }
2382
2383 /* worlds */
2384 for (id = static_cast<ID *>(bmain->worlds.first); id; id = static_cast<ID *>(id->next)) {
2385 World *wo = (World *)id;
2386
2387 if (G.debug & G_DEBUG) {
2388 printf("\tconverting world %s\n", id->name + 2);
2389 }
2390
2391 /* we're only interested in the IPO */
2392 if (wo->ipo) {
2393 /* Add AnimData block */
2395
2396 /* Convert World data... */
2397 ipo_to_animdata(bmain, id, wo->ipo, nullptr, nullptr, nullptr);
2398
2399 if (adt->action && !action_is_layered(*adt->action)) {
2400 adt->action->idroot = wo->ipo->blocktype;
2401 }
2402
2403 id_us_min(&wo->ipo->id);
2404 wo->ipo = nullptr;
2405 }
2406 }
2407
2408 /* sequence strips */
2409 for (id = static_cast<ID *>(bmain->scenes.first); id; id = static_cast<ID *>(id->next)) {
2410 Scene *scene = (Scene *)id;
2411 Editing *ed = scene->ed;
2412 if (ed && ed->seqbasep) {
2413 Seq_callback_data cb_data = {bmain, scene, BKE_animdata_ensure_id(id)};
2414 seq::for_each_callback(&ed->seqbase, strip_convert_callback, &cb_data);
2415 }
2416 }
2417
2418 /* textures */
2419 for (id = static_cast<ID *>(bmain->textures.first); id; id = static_cast<ID *>(id->next)) {
2420 Tex *te = (Tex *)id;
2421
2422 if (G.debug & G_DEBUG) {
2423 printf("\tconverting texture %s\n", id->name + 2);
2424 }
2425
2426 /* we're only interested in the IPO */
2427 if (te->ipo) {
2428 /* Add AnimData block */
2430
2431 /* Convert Texture data... */
2432 ipo_to_animdata(bmain, id, te->ipo, nullptr, nullptr, nullptr);
2433
2434 if (adt->action && !action_is_layered(*adt->action)) {
2435 adt->action->idroot = te->ipo->blocktype;
2436 }
2437
2438 id_us_min(&te->ipo->id);
2439 te->ipo = nullptr;
2440 }
2441 }
2442
2443 /* cameras */
2444 for (id = static_cast<ID *>(bmain->cameras.first); id; id = static_cast<ID *>(id->next)) {
2445 Camera *ca = (Camera *)id;
2446
2447 if (G.debug & G_DEBUG) {
2448 printf("\tconverting camera %s\n", id->name + 2);
2449 }
2450
2451 /* we're only interested in the IPO */
2452 if (ca->ipo) {
2453 /* Add AnimData block */
2455
2456 /* Convert Camera data... */
2457 ipo_to_animdata(bmain, id, ca->ipo, nullptr, nullptr, nullptr);
2458
2459 if (adt->action && !action_is_layered(*adt->action)) {
2460 adt->action->idroot = ca->ipo->blocktype;
2461 }
2462
2463 id_us_min(&ca->ipo->id);
2464 ca->ipo = nullptr;
2465 }
2466 }
2467
2468 /* lights */
2469 for (id = static_cast<ID *>(bmain->lights.first); id; id = static_cast<ID *>(id->next)) {
2470 Light *la = (Light *)id;
2471
2472 if (G.debug & G_DEBUG) {
2473 printf("\tconverting light %s\n", id->name + 2);
2474 }
2475
2476 /* we're only interested in the IPO */
2477 if (la->ipo) {
2478 /* Add AnimData block */
2480
2481 /* Convert Light data... */
2482 ipo_to_animdata(bmain, id, la->ipo, nullptr, nullptr, nullptr);
2483
2484 if (adt->action && !action_is_layered(*adt->action)) {
2485 adt->action->idroot = la->ipo->blocktype;
2486 }
2487
2488 id_us_min(&la->ipo->id);
2489 la->ipo = nullptr;
2490 }
2491 }
2492
2493 /* curves */
2494 for (id = static_cast<ID *>(bmain->curves.first); id; id = static_cast<ID *>(id->next)) {
2495 Curve *cu = (Curve *)id;
2496
2497 if (G.debug & G_DEBUG) {
2498 printf("\tconverting curve %s\n", id->name + 2);
2499 }
2500
2501 /* we're only interested in the IPO */
2502 if (cu->ipo) {
2503 /* Add AnimData block */
2505
2506 /* Convert Curve data... */
2507 ipo_to_animdata(bmain, id, cu->ipo, nullptr, nullptr, nullptr);
2508
2509 if (adt->action && !action_is_layered(*adt->action)) {
2510 adt->action->idroot = cu->ipo->blocktype;
2511 }
2512
2513 id_us_min(&cu->ipo->id);
2514 cu->ipo = nullptr;
2515 }
2516 }
2517
2518 /* --------- Unconverted Animation Data ------------------ */
2519 /* For Animation data which may not be directly connected (i.e. not linked) to any other
2520 * data, we need to perform a separate pass to make sure that they are converted to standalone
2521 * Actions which may then be able to be reused. This does mean that we will be going over data
2522 * that's already been converted, but there are no problems with that.
2523 *
2524 * The most common case for this will be Action Constraints, or IPO's with Fake-Users.
2525 * We collect all drivers that were found into a temporary collection, and free them in one go,
2526 * as they're impossible to resolve.
2527 */
2528
2529 /* actions */
2530 for (id = static_cast<ID *>(bmain->actions.first); id; id = static_cast<ID *>(id->next)) {
2531 bAction *act = (bAction *)id;
2532
2533 if (G.debug & G_DEBUG) {
2534 printf("\tconverting action %s\n", id->name + 2);
2535 }
2536
2537 /* if old action, it will be object-only... */
2538 if (act->chanbase.first) {
2539 act->idroot = ID_OB;
2540 }
2541
2542 /* be careful! some of the actions we encounter will be converted ones... */
2543 ensure_action_is_layered(nullptr, act, &act->groups, &act->curves, &drivers);
2544 }
2545
2546 /* ipo's */
2547 for (id = static_cast<ID *>(bmain->ipo.first); id; id = static_cast<ID *>(id->next)) {
2548 Ipo *ipo = (Ipo *)id;
2549
2550 if (G.debug & G_DEBUG) {
2551 printf("\tconverting ipo %s\n", id->name + 2);
2552 }
2553
2554 /* most likely this IPO has already been processed, so check if any curves left to convert */
2555 if (ipo->curve.first) {
2556 bAction *new_act;
2557
2558 /* add a new action for this, and convert all data into that action */
2559 new_act = BKE_action_add(bmain, id->name + 2);
2560 ipo_to_animato(nullptr, ipo, nullptr, nullptr, nullptr, nullptr, &new_act->curves, &drivers);
2561 new_act->idroot = ipo->blocktype;
2562
2563 /* Upgrade the resulting Animato action to a layered action. */
2566 }
2567
2568 /* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */
2569 ipo->id.us = 0;
2570 ipo->id.flag &= ~ID_FLAG_FAKEUSER;
2571 }
2572
2573 /* free unused drivers from actions + ipos */
2574 BKE_fcurves_free(&drivers);
2575
2576 if (G.debug & G_DEBUG) {
2577 printf("INFO: Animato convert done\n");
2578 }
2579}
Functions and classes to work with Actions.
Versioning of old animation data. Most animation versioning code lives in the versioning_xxx....
Blender kernel action and pose functionality.
void action_groups_add_channel(bAction *act, bActionGroup *agrp, FCurve *fcurve)
bAction * BKE_action_add(Main *bmain, const char name[])
bActionGroup * BKE_action_group_find_name(bAction *act, const char name[])
AnimData * BKE_animdata_ensure_id(ID *id)
Definition anim_data.cc:96
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:82
FCurve * BKE_fcurve_copy(const FCurve *fcu)
FCurve * BKE_fcurve_create()
FModifier * add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu)
void BKE_fcurves_free(ListBase *list)
struct DriverVar * driver_add_new_variable(struct ChannelDriver *driver)
void driver_change_variable_type(struct DriverVar *dvar, int type)
@ G_DEBUG
IDTypeInfo IDType_ID_IP
Definition ipo.cc:164
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition BKE_idtype.hh:46
@ IDTYPE_FLAGS_NO_COPY
Definition BKE_idtype.hh:30
@ IDTYPE_FLAGS_NO_LIBLINKING
Definition BKE_idtype.hh:32
KeyBlock * BKE_keyblock_find_by_index(Key *key, int index)
Definition key.cc:1940
void id_us_min(ID *id)
Definition lib_id.cc:361
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(data_, id_super_, cb_flag_)
@ IDWALK_CB_NOP
LibraryForeachIDFlag BKE_lib_query_foreachid_process_flags_get(const LibraryForeachIDData *data)
Definition lib_query.cc:129
@ IDWALK_DO_DEPRECATED_POINTERS
bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, bool is_liboverride)
void BKE_nlatrack_set_active(ListBase *tracks, NlaTrack *nlt)
NlaTrack * BKE_nlatrack_new_tail(ListBase *nla_tracks, const bool is_liboverride)
void BKE_nlastrip_validate_name(AnimData *adt, NlaStrip *strip)
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.cc:36
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition BLI_dynstr.cc:55
BLI_INLINE void BLI_endian_switch_int16(short *val) ATTR_NONNULL(1)
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:270
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
#define M_PI
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
void BLI_uniquename(const struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_maxncpy) ATTR_NONNULL(1
unsigned int uint
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define STREQ(a, b)
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
Definition readfile.cc:5244
#define BLO_read_struct_list(reader, struct_name, list)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
#define BLO_read_struct(reader, struct_name, ptr_p)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:182
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
@ INDEX_ID_IP
Definition DNA_ID.h:1192
@ ID_FLAG_FAKEUSER
Definition DNA_ID.h:682
@ ID_CA
@ ID_AR
@ ID_TE
@ ID_LA
@ ID_KE
@ ID_SO
@ ID_SCE
@ ID_WO
@ ID_MA
@ ID_CU_LEGACY
@ ID_OB
@ ID_PA
@ AGRP_SELECTED
@ AGRP_MUTED
@ NLASTRIP_FLAG_ACTIVE
@ NLASTRIP_FLAG_AUTO_BLENDS
@ NLASTRIP_FLAG_REVERSE
@ NLASTRIP_FLAG_MUTED
@ NLASTRIP_FLAG_SELECT
@ NLASTRIP_FLAG_SYNC_LENGTH
@ DTAR_TRANSCHAN_ROTZ
@ DTAR_TRANSCHAN_SCALEX
@ DTAR_TRANSCHAN_LOCX
@ DTAR_TRANSCHAN_LOCY
@ DTAR_TRANSCHAN_ROTX
@ DTAR_TRANSCHAN_LOCZ
@ DTAR_TRANSCHAN_ROTY
@ FCM_EXTRAPOLATE_CYCLIC
@ FCM_EXTRAPOLATE_CYCLIC_OFFSET
@ DRIVER_TYPE_AVERAGE
@ DRIVER_TYPE_PYTHON
@ DVAR_TYPE_TRANSFORM_CHAN
@ DVAR_TYPE_ROT_DIFF
@ FMODIFIER_TYPE_CYCLES
@ NLASTRIP_EXTEND_NOTHING
@ DTAR_FLAG_LOCALSPACE
@ NLASTRIP_MODE_REPLACE
@ NLASTRIP_MODE_ADD
@ FCURVE_DISABLED
@ FCURVE_MUTED
@ FCURVE_INT_VALUES
@ FCURVE_ACTIVE
@ FCURVE_SELECTED
@ FCURVE_DISCRETE_VALUES
@ FCURVE_PROTECTED
@ FCURVE_VISIBLE
@ CAM_ORTHO
@ HD_AUTO_ANIM
@ HD_AUTO
@ BEZT_IPO_CONST
@ BEZT_KEYTYPE_KEYFRAME
#define TE_MG_GAIN
#define MAP_SIZE_Z
#define CAM_SHIFT_X
#define MAP_OFS_Y
#define STRIP_FAC1
#define SND_ATTEN
#define AC_EUL_Z
#define WO_ZEN_G
#define MAP_SIZE_X
#define TE_NTYPE
#define PART_DAMP
#define OB_COL_R
#define TE_VNW2
#define IPO_MIXED
#define MA_HASIZE
#define MA_MAP17
#define OB_DROT_Z
#define AC_QUAT_Z
#define OB_COL_A
#define OB_DSIZE_Z
#define MA_COL_G
#define MA_SPEC
#define PART_PD_FSTR
#define TE_VN_COLT
#define OB_LOC_X
#define STRIP_FAC_SPEED
#define TE_NSIZE
#define TE_DISTA
#define AC_LOC_Z
#define TE_VNW1
#define OB_ROT_Y
#define OB_LAY
#define CO_HEADTAIL
#define MA_IOR
#define MA_FRESTRA
#define WO_MISTHI
#define MA_MAP10
#define TE_VN_DISTM
#define OB_PD_FSTR
#define MAP_OFS_Z
#define OB_SIZE_Z
#define MA_MAP2
#define PART_AVE
#define WO_MISTDI
#define PART_PD_FMAXD
#define MA_MAP15
#define MAP_NORF
#define MAP_R
#define MA_MAP11
#define AC_QUAT_W
#define PART_PD_FFALL
#define OB_DSIZE_Y
#define PART_CLUMP
#define MA_MIR_G
#define MA_ADD
#define OB_LOC_Y
#define MAP_COLF
#define OB_PD_PERM
#define MA_SPEC_B
#define LA_ENERGY
#define AC_SIZE_Y
#define SND_PITCH
#define TE_N_BAS1
#define MAP_SIZE_Y
#define MA_MAP7
#define MA_HARD
#define IPO_DIR
#define WO_ZEN_R
#define WO_EXPOS
#define LA_QUAD2
#define PART_PD2_FFALL
#define CAM_SHIFT_Y
#define OB_ROT_Z
#define OB_DLOC_Y
#define AC_QUAT_Y
#define LA_COL_B
#define AC_SIZE_Z
#define OB_DSIZE_X
#define LA_HALOINT
#define MA_MAP4
#define IPO_MUTE
#define TE_VNMEXP
#define MA_AMB
#define LA_SPOTSI
#define OB_PD_FMAXD
#define LA_COL_G
#define PART_KINK_FREQ
#define PART_PD2_FMAXD
#define WO_HOR_G
#define TE_VNW3
#define AC_LOC_Y
#define MA_MAP5
#define IPO_VISIBLE
#define PART_KINK_SHAPE
#define AC_LOC_X
#define OB_ROT_DIFF
#define IPO_DRIVER_TYPE_PYTHON
#define CAM_LENS
#define CAM_STA
#define MAP_OFS_X
#define PART_LENGTH
#define LA_DIST
#define AC_QUAT_X
#define SND_VOLUME
#define MA_SPTR
#define MA_MAP13
#define TE_NDEPTH
#define OB_LOC_Z
#define MA_MAP1
#define PART_SIZE
#define MAP_DISP
#define MAP_DVAR
#define CAM_END
#define IPO_AUTO_HORIZ
#define TE_MG_OFF
#define AC_EUL_Y
#define DRIVER_NAME_OFFS
#define OB_COL_B
#define AC_EUL_X
#define MAP_B
#define IPO_CYCL
#define MA_MAP16
#define WO_MISI
#define MA_MAP9
#define OB_SIZE_X
#define SND_PANNING
#define OB_COL_G
#define TE_BRIGHT
#define MA_SPEC_R
#define MA_FRESTRAI
#define MA_TRANSLU
#define WO_ZEN_B
#define MA_MAP3
#define MA_MAP18
#define MA_FRESMIRI
#define IPO_PROTECT
#define MA_RAYM
#define LA_QUAD1
#define TE_N_BAS2
#define MA_ALPHA
#define TE_MG_TYP
#define TE_VNW4
#define OB_ROT_X
#define IPO_SELECT
#define TE_COL_G
#define MA_MAP6
#define STRIP_FAC_OPACITY
#define TE_COL_R
#define OB_PD_FFALL
#define PART_GRAV_X
#define PART_KINK_AMP
#define TE_ISCA
#define LA_SPOTBL
#define PART_BROWN
#define MA_COL_B
#define AC_SIZE_X
#define MAP_VARF
#define WO_HOR_B
#define MA_COL_R
#define MA_MAP12
#define IPO_HORIZ
#define TE_TURB
#define PART_BB_TILT
#define MAP_G
#define PART_GRAV_Y
#define WO_MISTSTA
#define OB_DLOC_Z
#define OB_DROT_Y
#define MA_FRESMIR
#define OB_SIZE_Y
#define TE_MGH
#define PART_PD2_FSTR
#define CAM_YF_FDIST
#define OB_PD_SDAMP
#define TE_MG_LAC
#define MA_MIR_R
#define MA_MAP8
#define MA_MIR_B
#define IPO_ACTIVE
#define PART_GRAV_Z
#define LA_COL_R
#define CO_ENFORCE
#define TE_CONTRA
#define MA_EMIT
#define OB_PD_RDAMP
#define MA_MAP14
#define TE_COL_B
#define TE_MG_OCT
#define IPO_CYCLX
#define MA_SPEC_G
#define CAM_YF_APERT
#define PART_DRAG
#define MA_REF
#define WO_HOR_R
#define OB_DROT_X
#define OB_DLOC_X
@ ACTSTRIPMODE_ADD
@ ACTSTRIP_ACTIVE
@ ACTSTRIP_MUTE
@ ACTSTRIP_SELECT
@ ACTSTRIP_REVERSE
@ ACTSTRIP_LOCK_ACTION
@ ACTSTRIP_HOLDLASTFRAME
@ ACTSTRIP_AUTO_BLENDS
Object is a sort of wrapper for general info.
@ SEQ_IPO_FRAME_LOCKED
@ SEQ_USE_EFFECT_DEFAULT_FADE
@ STRIP_TYPE_SCENE
@ STRIP_TYPE_IMAGE
@ STRIP_TYPE_MOVIE
@ STRIP_TYPE_SPEED
@ STRIP_TYPE_COLOR
@ STRIP_TYPE_META
Read Guarded memory(de)allocation.
BMesh const char void * data
static void mul(btAlignedObjectArray< T > &items, const Q &value)
#define offsetof(t, d)
#define printf(...)
#define ID_CO
#define MAX_ID_NAME
#define ID_REAL_USERS(id)
#define ID_SEQ
#define GS(a)
#define ID_PO
#define FILTER_ID_IP
static const char * texture_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:592
static char * shapekey_adrcodes_to_paths(ID *id, int adrcode, int *)
Definition ipo.cc:442
static const char * material_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:679
static AdrBit2Path ob_layer_bits[]
Definition ipo.cc:211
static void ipo_blend_read_data(BlendDataReader *reader, ID *id)
Definition ipo.cc:123
static void ipo_to_animdata(Main *bmain, ID *id, Ipo *ipo, char actname[], char constname[], Strip *strip)
Definition ipo.cc:1894
static void ipo_foreach_id(ID *id, LibraryForeachIDData *data)
Definition ipo.cc:109
static void nlastrips_to_animdata(ID *id, ListBase *strips)
Definition ipo.cc:2000
static const char * world_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:888
static const char * camera_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:772
static void action_to_animdata(ID *id, bAction *act)
Definition ipo.cc:1969
static const char * ob_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:249
static const char * pchan_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:364
static bool strip_convert_callback(Strip *strip, void *userdata)
Definition ipo.cc:2101
static const char * sound_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:862
static char * get_rna_access(ID *id, int blocktype, int adrcode, const char actname[], const char constname[], Strip *strip, int *r_array_index)
Definition ipo.cc:1029
static void convert_pre_animato_action_to_animato_action_in_place(ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
Definition ipo.cc:1806
static const char * light_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:817
static void ensure_action_is_layered(ID *id, bAction *act, ListBase *groups, ListBase *curves, ListBase *drivers)
Definition ipo.cc:1863
static AdrBit2Path * adrcode_bitmaps_to_paths(int blocktype, int adrcode, int *tot)
Definition ipo.cc:232
static const char * constraint_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:421
#define RET_ABP(items)
Definition ipo.cc:224
static void icu_to_fcurves(ID *id, ListBase *groups, ListBase *list, IpoCurve *icu, char *actname, char *constname, Strip *strip, int muteipo)
Definition ipo.cc:1407
static void ipo_to_animato(ID *id, Ipo *ipo, char actname[], char constname[], Strip *strip, ListBase *animgroups, ListBase *anim, ListBase *drivers)
Definition ipo.cc:1708
static short adrcode_to_dtar_transchan(short adrcode)
Definition ipo.cc:1221
static const char * particle_adrcodes_to_paths(int adrcode, int *r_array_index)
Definition ipo.cc:934
static void fcurve_add_to_list(ListBase *groups, ListBase *list, FCurve *fcu, char *grpname, int muteipo)
Definition ipo.cc:1333
static const char * mtex_adrcodes_to_paths(int adrcode, int *)
Definition ipo.cc:472
static void ipo_free_data(ID *id)
Definition ipo.cc:80
static ChannelDriver * idriver_to_cdriver(IpoDriver *idriver)
Definition ipo.cc:1251
void do_versions_ipos_to_layered_actions(Main *bmain)
Definition ipo.cc:2147
#define LOG(severity)
Definition log.h:32
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void convert_legacy_animato_action(bAction &dna_action)
Definition versioning.cc:81
void tag_action_user_for_slotted_actions_conversion(ID &animated_id)
bool action_is_layered(const bAction &dna_action)
Definition versioning.cc:37
bool assign_action(bAction *action, ID &animated_id)
void for_each_callback(ListBase *seqbase, ForEachFunc callback, void *user_data)
Definition iterator.cc:59
int array_index
Definition ipo.cc:204
int bit
Definition ipo.cc:202
const char * path
Definition ipo.cc:203
bAction * action
ListBase drivers
ListBase nla_tracks
float vec[3][3]
char expression[256]
char pchan_name[64]
DriverTarget targets[8]
char * rna_path
ChannelDriver * driver
BezTriple * bezt
short extend
int array_index
unsigned int totvert
ListBase modifiers
Definition DNA_ID.h:404
int us
Definition DNA_ID.h:425
short flag
Definition DNA_ID.h:420
void * next
Definition DNA_ID.h:407
char name[66]
Definition DNA_ID.h:415
struct BezTriple * bezt
IpoDriver * driver
short totvert
short blocktype
struct BPoint * bp
short extrap
short adrcode
struct IpoCurve * next
char name[128]
short blocktype
struct Object * ob
short adrcode
short muteipo
ListBase curve
short blocktype
char name[64]
void * last
void * first
ListBase scenes
Definition BKE_main.hh:245
ListBase textures
Definition BKE_main.hh:252
ListBase actions
Definition BKE_main.hh:269
ListBase ipo
Definition BKE_main.hh:258
ListBase lights
Definition BKE_main.hh:255
ListBase materials
Definition BKE_main.hh:251
ListBase shapekeys
Definition BKE_main.hh:259
ListBase cameras
Definition BKE_main.hh:256
ListBase curves
Definition BKE_main.hh:249
ListBase worlds
Definition BKE_main.hh:260
short versionfile
Definition BKE_main.hh:156
ListBase objects
Definition BKE_main.hh:247
short blendmode
short extendmode
bAction * act
ListBase constraints
struct bPose * pose
struct Editing * ed
Scene * scene
Definition ipo.cc:2097
AnimData * adt
Definition ipo.cc:2098
char name[64]
struct bAction * act
struct bActionStrip * next
ListBase modifiers
ListBase curves
ListBase groups
struct bConstraintChannel * next
ListBase chanbase
i
Definition text_draw.cc:230
#define N_(msgid)
uint8_t flag
Definition wm_window.cc:139