Blender V5.0
rna_animation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10
11#include "DNA_anim_types.h"
12
13#include "BLT_translation.hh"
14
15#include "BKE_lib_override.hh"
16#include "BKE_nla.hh"
17
18#include "RNA_define.hh"
19#include "RNA_enum_types.hh"
20
21#include "rna_internal.hh"
22
23#include "WM_api.hh"
24#include "WM_types.hh"
25
26#include "ED_keyframing.hh"
27
28using namespace blender;
29
30/* exported for use in API */
32 {KSP_GROUP_NAMED, "NAMED", 0, "Named Group", ""},
33 {KSP_GROUP_NONE, "NONE", 0, "None", ""},
34 {KSP_GROUP_KSNAME, "KEYINGSET", 0, "Keying Set Name", ""},
35 {0, nullptr, 0, nullptr, nullptr},
36};
37
38/* It would be cool to get rid of this 'INSERTKEY_' prefix in 'py strings' values,
39 * but it would break existing
40 * exported keyingset... :/
41 */
44 "INSERTKEY_NEEDED",
45 0,
46 "Only Needed",
47 "Only insert keyframes where they're needed in the relevant F-Curves"},
49 "INSERTKEY_VISUAL",
50 0,
51 "Visual Keying",
52 "Insert keyframes based on 'visual transforms'"},
53 {0, nullptr, 0, nullptr, nullptr},
54};
55
56/* Contains additional flags suitable for use in Python API functions. */
59 "INSERTKEY_NEEDED",
60 0,
61 "Only Needed",
62 "Only insert keyframes where they're needed in the relevant F-Curves"},
64 "INSERTKEY_VISUAL",
65 0,
66 "Visual Keying",
67 "Insert keyframes based on 'visual transforms'"},
69 "INSERTKEY_REPLACE",
70 0,
71 "Replace Existing",
72 "Only replace existing keyframes"},
74 "INSERTKEY_AVAILABLE",
75 0,
76 "Only Available",
77 "Don't create F-Curves when they don't already exist"},
79 "INSERTKEY_CYCLE_AWARE",
80 0,
81 "Cycle Aware Keying",
82 "When inserting into a curve with cyclic extrapolation, remap the keyframe inside "
83 "the cycle time range, and if changing an end key, also update the other one"},
84 {0, nullptr, 0, nullptr, nullptr},
85};
86
87#ifdef RNA_RUNTIME
88
89# include <algorithm>
90
91# include "BLI_math_base.h"
92
93# include "BKE_anim_data.hh"
94# include "BKE_animsys.h"
95# include "BKE_fcurve.hh"
96# include "BKE_nla.hh"
97
98# include "ANIM_action.hh"
99# include "ANIM_action_legacy.hh"
100# include "ANIM_keyingsets.hh"
101
102# include "DEG_depsgraph.hh"
103# include "DEG_depsgraph_build.hh"
104
105# include "DNA_object_types.h"
106
107# include "ED_anim_api.hh"
108
109# include "WM_api.hh"
110
111# include "UI_interface_icons.hh"
112
113static void rna_AnimData_update(Main *bmain, Scene * /*scene*/, PointerRNA *ptr)
114{
115 ID *id = ptr->owner_id;
116
117 ANIM_id_update(bmain, id);
118}
119
120static void rna_AnimData_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
121{
123
124 rna_AnimData_update(bmain, scene, ptr);
125}
126
127void rna_generic_action_slot_handle_override_diff(Main *bmain,
129 const bAction *action_a,
130 const bAction *action_b)
131{
132 rna_property_override_diff_default(bmain, rnadiff_ctx);
133
134 if (rnadiff_ctx.comparison || (rnadiff_ctx.report_flag & RNA_OVERRIDE_MATCH_RESULT_CREATED)) {
135 /* Default diffing found a difference, no need to go further. */
136 return;
137 }
138
139 if (action_a == action_b) {
140 /* Action is unchanged, it's fine to mark the slot handle as unchanged as well. */
141 return;
142 }
143
144 /* Sign doesn't make sense here, as the numerical values are the same. */
145 rnadiff_ctx.comparison = 1;
146
147 /* The remainder of this function was taken from rna_property_override_diff_default(). It's just
148 * formatted a little differently to allow for early returns. */
149
150 const bool do_create = rnadiff_ctx.liboverride != nullptr &&
151 (rnadiff_ctx.liboverride_flags & RNA_OVERRIDE_COMPARE_CREATE) != 0 &&
152 rnadiff_ctx.rna_path != nullptr;
153 if (!do_create) {
154 /* Not enough info to create an override operation, so bail out. */
155 return;
156 }
157
158 /* Create the override operation. */
159 bool created = false;
161 rnadiff_ctx.liboverride, rnadiff_ctx.rna_path, &created);
162
163 if (op && created) {
165 op, LIBOVERRIDE_OP_REPLACE, nullptr, nullptr, {}, {}, -1, -1, true, nullptr, nullptr);
167 }
168}
169
175static void rna_AnimData_slot_handle_override_diff(Main *bmain,
177{
178 const AnimData *adt_a = static_cast<AnimData *>(rnadiff_ctx.prop_a->ptr->data);
179 const AnimData *adt_b = static_cast<AnimData *>(rnadiff_ctx.prop_b->ptr->data);
180
181 rna_generic_action_slot_handle_override_diff(bmain, rnadiff_ctx, adt_a->action, adt_b->action);
182}
183
184static int rna_AnimData_action_editable(const PointerRNA *ptr, const char ** /*r_info*/)
185{
186 BLI_assert(ptr->type == &RNA_AnimData);
187 AnimData *adt = static_cast<AnimData *>(ptr->data);
188 if (!adt) {
189 return PROP_EDITABLE;
190 }
192}
193
194static PointerRNA rna_AnimData_action_get(PointerRNA *ptr)
195{
196 ID &animated_id = *ptr->owner_id;
197 animrig::Action *action = animrig::get_action(animated_id);
198 if (!action) {
199 return PointerRNA_NULL;
200 };
201 return RNA_id_pointer_create(&action->id);
202}
203
204static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value, ReportList *reports)
205{
206 using namespace blender::animrig;
207 BLI_assert(ptr->owner_id);
208 ID &animated_id = *ptr->owner_id;
209
210 Action *action = static_cast<Action *>(value.data);
211 if (!assign_action(action, animated_id)) {
212 BKE_report(reports, RPT_ERROR, "Could not change action");
213 }
214}
215
216static void rna_AnimData_tmpact_set(PointerRNA *ptr, PointerRNA value, ReportList *reports)
217{
218 ID *owner_id = ptr->owner_id;
219 AnimData *adt = (AnimData *)ptr->data;
220 BLI_assert(adt != nullptr);
221
222 bAction *action = static_cast<bAction *>(value.data);
223 if (!blender::animrig::assign_tmpaction(action, {*owner_id, *adt})) {
224 BKE_report(reports, RPT_WARNING, "Failed to set temporary action");
225 }
226}
227
228static void rna_AnimData_tweakmode_set(PointerRNA *ptr, const bool value)
229{
230 ID *animated_id = ptr->owner_id;
231 AnimData *adt = (AnimData *)ptr->data;
232
233 /* NOTE: technically we should also set/unset SCE_NLA_EDIT_ON flag on the
234 * scene which is used to make polling tests faster, but this flag is weak
235 * and can easily break e.g. by changing layer visibility. This needs to be
236 * dealt with at some point. */
237
238 if (value) {
239 BKE_nla_tweakmode_enter({*animated_id, *adt});
240 }
241 else {
242 BKE_nla_tweakmode_exit({*animated_id, *adt});
243 }
244}
245
254bool rna_AnimData_tweakmode_override_apply(Main * /*bmain*/,
256{
257 PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
258 PointerRNA *ptr_src = &rnaapply_ctx.ptr_src;
259
260 AnimData *anim_data_dst = (AnimData *)ptr_dst->data;
261 AnimData *anim_data_src = (AnimData *)ptr_src->data;
262
263 anim_data_dst->flag = (anim_data_dst->flag & ~ADT_NLA_EDIT_ON) |
264 (anim_data_src->flag & ADT_NLA_EDIT_ON);
265
266 /* There are many more flags & pointers to deal with when switching NLA tweak mode. This has to
267 * be handled once all the NLA tracks & strips are available, though. It's done in a post-process
268 * step, see BKE_nla_liboverride_post_process(). */
269 return true;
270}
271
272void rna_generic_action_slot_handle_set(blender::animrig::slot_handle_t slot_handle_to_assign,
273 ID &animated_id,
274 bAction *&action_ptr_ref,
275 blender::animrig::slot_handle_t &slot_handle_ref,
276 char *slot_name)
277{
278 using namespace blender::animrig;
279
281 slot_handle_to_assign, animated_id, action_ptr_ref, slot_handle_ref, slot_name);
282
283 /* Unfortunately setters for PROP_INT do not receive a `reports` parameter, so
284 * report to the Window Manager report list instead. */
285 switch (result) {
287 break;
290 break;
293 "This slot is not suitable for this data-block type (%c%c)",
294 animated_id.name[0],
295 animated_id.name[1]);
296 break;
298 WM_global_report(RPT_ERROR, "Cannot set slot without an assigned Action.");
299 break;
300 }
301}
302
303static void rna_AnimData_action_slot_handle_set(
304 PointerRNA *ptr, const blender::animrig::slot_handle_t new_slot_handle)
305{
306 ID &animated_id = *ptr->owner_id;
307 AnimData *adt = BKE_animdata_from_id(&animated_id);
308
309 rna_generic_action_slot_handle_set(
310 new_slot_handle, animated_id, adt->action, adt->slot_handle, adt->last_slot_identifier);
311}
312
313static AnimData &rna_animdata(const PointerRNA *ptr)
314{
315 return *reinterpret_cast<AnimData *>(ptr->data);
316}
317
318PointerRNA rna_generic_action_slot_get(bAction *dna_action,
319 const animrig::slot_handle_t slot_handle)
320{
321 using namespace blender::animrig;
322
323 if (!dna_action || slot_handle == Slot::unassigned) {
324 return PointerRNA_NULL;
325 }
326
327 Action &action = dna_action->wrap();
328 Slot *slot = action.slot_for_handle(slot_handle);
329 if (!slot) {
330 return PointerRNA_NULL;
331 }
332 return RNA_pointer_create_discrete(&action.id, &RNA_ActionSlot, slot);
333}
334
335static PointerRNA rna_AnimData_action_slot_get(PointerRNA *ptr)
336{
337 AnimData &adt = rna_animdata(ptr);
338 return rna_generic_action_slot_get(adt.action, adt.slot_handle);
339}
340
341void rna_generic_action_slot_set(PointerRNA rna_slot_to_assign,
342 ID &animated_id,
343 bAction *&action_ptr_ref,
344 blender::animrig::slot_handle_t &slot_handle_ref,
345 char *slot_name,
346 ReportList *reports)
347{
348 using namespace blender::animrig;
349
350 ActionSlot *dna_slot = static_cast<ActionSlot *>(rna_slot_to_assign.data);
351 Slot *slot = dna_slot ? &dna_slot->wrap() : nullptr;
352
354 slot, animated_id, action_ptr_ref, slot_handle_ref, slot_name);
355
356 switch (result) {
358 break;
360 BKE_reportf(reports,
361 RPT_ERROR,
362 "This slot (%s) does not belong to the assigned Action",
363 slot->identifier);
364 break;
366 BKE_reportf(reports,
367 RPT_ERROR,
368 "This slot (%s) is not suitable for this data-block type (%c%c)",
369 slot->identifier,
370 animated_id.name[0],
371 animated_id.name[1]);
372 break;
374 BKE_report(reports, RPT_ERROR, "Cannot set slot without an assigned Action.");
375 break;
376 }
377}
378
379static void rna_AnimData_action_slot_set(PointerRNA *ptr, PointerRNA value, ReportList *reports)
380{
381 ID *animated_id = ptr->owner_id;
382 AnimData *adt = BKE_animdata_from_id(animated_id);
383 if (!adt) {
384 BKE_report(reports, RPT_ERROR, "Cannot set slot without an assigned Action.");
385 return;
386 }
387
388 rna_generic_action_slot_set(
389 value, *animated_id, adt->action, adt->slot_handle, adt->last_slot_identifier, reports);
390}
391
392static void rna_AnimData_action_slot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
393{
394 /* TODO: see if this is still necessary. */
396 rna_AnimData_dependency_update(bmain, scene, ptr);
397}
398
406bool rna_iterator_generic_action_suitable_slots_skip(CollectionPropertyIterator *iter, void *data)
407{
408 using animrig::Slot;
409
410 /* Get the current Slot being iterated over. */
411 const Slot **slot_ptr_ptr = static_cast<const Slot **>(data);
412 BLI_assert(slot_ptr_ptr);
413 BLI_assert(*slot_ptr_ptr);
414 const Slot &slot = **slot_ptr_ptr;
415
416 /* Get the animated ID. */
417 const ID *animated_id = iter->parent.owner_id;
418 BLI_assert(animated_id);
419
420 /* Skip this Slot if it's not suitable for the animated ID. */
421 return !slot.is_suitable_for(*animated_id);
422}
423
424void rna_iterator_generic_action_suitable_slots_begin(CollectionPropertyIterator *iter,
425 PointerRNA *owner_ptr,
426 bAction *assigned_action)
427{
428 if (!assigned_action) {
429 /* No action means no slots. */
430 rna_iterator_array_begin(iter, owner_ptr, nullptr, 0, 0, 0, nullptr);
431 return;
432 }
433
434 animrig::Action &action = assigned_action->wrap();
435 Span<animrig::Slot *> slots = action.slots();
437 owner_ptr,
438 (void *)slots.data(),
439 sizeof(animrig::Slot *),
440 slots.size(),
441 0,
442 rna_iterator_generic_action_suitable_slots_skip);
443}
444
445static void rna_iterator_animdata_action_suitable_slots_begin(CollectionPropertyIterator *iter,
447{
448 rna_iterator_generic_action_suitable_slots_begin(iter, ptr, rna_animdata(ptr).action);
449}
450
451/* ****************************** */
452
453/* wrapper for poll callback */
454static bool RKS_POLL_rna_internal(KeyingSetInfo *ksi, bContext *C)
455{
456 extern FunctionRNA rna_KeyingSetInfo_poll_func;
457
458 ParameterList list;
459 FunctionRNA *func;
460 void *ret;
461 int ok;
462
464 func = &rna_KeyingSetInfo_poll_func; /* RNA_struct_find_function(&ptr, "poll"); */
465
466 RNA_parameter_list_create(&list, &ptr, func);
467 {
468 /* hook up arguments */
469 RNA_parameter_set_lookup(&list, "ksi", &ksi);
470 RNA_parameter_set_lookup(&list, "context", &C);
471
472 /* execute the function */
473 ksi->rna_ext.call(C, &ptr, func, &list);
474
475 /* read the result */
476 RNA_parameter_get_lookup(&list, "ok", &ret);
477 ok = *(bool *)ret;
478 }
480
481 return ok;
482}
483
484/* wrapper for iterator callback */
485static void RKS_ITER_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks)
486{
487 extern FunctionRNA rna_KeyingSetInfo_iterator_func;
488
489 ParameterList list;
490 FunctionRNA *func;
491
493 func = &rna_KeyingSetInfo_iterator_func; /* RNA_struct_find_function(&ptr, "poll"); */
494
495 RNA_parameter_list_create(&list, &ptr, func);
496 {
497 /* hook up arguments */
498 RNA_parameter_set_lookup(&list, "ksi", &ksi);
499 RNA_parameter_set_lookup(&list, "context", &C);
500 RNA_parameter_set_lookup(&list, "ks", &ks);
501
502 /* execute the function */
503 ksi->rna_ext.call(C, &ptr, func, &list);
504 }
506}
507
508/* wrapper for generator callback */
509static void RKS_GEN_rna_internal(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, PointerRNA *data)
510{
511 extern FunctionRNA rna_KeyingSetInfo_generate_func;
512
513 ParameterList list;
514 FunctionRNA *func;
515
517 func = &rna_KeyingSetInfo_generate_func; /* RNA_struct_find_generate(&ptr, "poll"); */
518
519 RNA_parameter_list_create(&list, &ptr, func);
520 {
521 /* hook up arguments */
522 RNA_parameter_set_lookup(&list, "ksi", &ksi);
523 RNA_parameter_set_lookup(&list, "context", &C);
524 RNA_parameter_set_lookup(&list, "ks", &ks);
525 RNA_parameter_set_lookup(&list, "data", data);
526
527 /* execute the function */
528 ksi->rna_ext.call(C, &ptr, func, &list);
529 }
531}
532
533/* ------ */
534
535/* XXX: the exact purpose of this is not too clear...
536 * maybe we want to revise this at some point? */
537static StructRNA *rna_KeyingSetInfo_refine(PointerRNA *ptr)
538{
539 KeyingSetInfo *ksi = (KeyingSetInfo *)ptr->data;
540 return (ksi->rna_ext.srna) ? ksi->rna_ext.srna : &RNA_KeyingSetInfo;
541}
542
543static bool rna_KeyingSetInfo_unregister(Main *bmain, StructRNA *type)
544{
545 KeyingSetInfo *ksi = static_cast<KeyingSetInfo *>(RNA_struct_blender_type_get(type));
546
547 if (ksi == nullptr) {
548 return false;
549 }
550
551 /* free RNA data referencing this */
554
556
557 /* unlink Blender-side data */
559 return true;
560}
561
562static StructRNA *rna_KeyingSetInfo_register(Main *bmain,
563 ReportList *reports,
564 void *data,
565 const char *identifier,
566 StructValidateFunc validate,
569{
570 const char *error_prefix = "Registering keying set info class:";
571 KeyingSetInfo dummy_ksi = {nullptr};
572 KeyingSetInfo *ksi;
573 bool have_function[3];
574
575 /* setup dummy type info to store static properties in */
576 /* TODO: perhaps we want to get users to register
577 * as if they're using 'KeyingSet' directly instead? */
578 PointerRNA dummy_ksi_ptr = RNA_pointer_create_discrete(nullptr, &RNA_KeyingSetInfo, &dummy_ksi);
579
580 /* validate the python class */
581 if (validate(&dummy_ksi_ptr, data, have_function) != 0) {
582 return nullptr;
583 }
584
585 if (strlen(identifier) >= sizeof(dummy_ksi.idname)) {
586 BKE_reportf(reports,
587 RPT_ERROR,
588 "%s '%s' is too long, maximum length is %d",
589 error_prefix,
590 identifier,
591 int(sizeof(dummy_ksi.idname)));
592 return nullptr;
593 }
594
595 /* check if we have registered this info before, and remove it */
597 if (ksi) {
598 BKE_reportf(reports,
599 RPT_INFO,
600 "%s '%s', bl_idname '%s' has been registered before, unregistering previous",
601 error_prefix,
602 identifier,
603 dummy_ksi.idname);
604
605 StructRNA *srna = ksi->rna_ext.srna;
606 if (!(srna && rna_KeyingSetInfo_unregister(bmain, srna))) {
607 BKE_reportf(reports,
608 RPT_ERROR,
609 "%s '%s', bl_idname '%s' %s",
610 error_prefix,
611 identifier,
612 dummy_ksi.idname,
613 srna ? "is built-in" : "could not be unregistered");
614 return nullptr;
615 }
616 }
617
618 /* create a new KeyingSetInfo type */
619 ksi = MEM_mallocN<KeyingSetInfo>("python keying set info");
620 memcpy(ksi, &dummy_ksi, sizeof(KeyingSetInfo));
621
622 /* set RNA-extensions info */
623 ksi->rna_ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, ksi->idname, &RNA_KeyingSetInfo);
624 ksi->rna_ext.data = data;
625 ksi->rna_ext.call = call;
626 ksi->rna_ext.free = free;
628
629 /* set callbacks */
630 /* NOTE: we really should have all of these... */
631 ksi->poll = (have_function[0]) ? RKS_POLL_rna_internal : nullptr;
632 ksi->iter = (have_function[1]) ? RKS_ITER_rna_internal : nullptr;
633 ksi->generate = (have_function[2]) ? RKS_GEN_rna_internal : nullptr;
634
635 /* add and register with other info as needed */
637
639
640 /* return the struct-rna added */
641 return ksi->rna_ext.srna;
642}
643
644/* ****************************** */
645
646static StructRNA *rna_ksPath_id_typef(PointerRNA *ptr)
647{
648 KS_Path *ksp = (KS_Path *)ptr->data;
649 return ID_code_to_RNA_type(ksp->idtype);
650}
651
652static int rna_ksPath_id_editable(const PointerRNA *ptr, const char ** /*r_info*/)
653{
654 KS_Path *ksp = (KS_Path *)ptr->data;
655 return (ksp->idtype) ? PROP_EDITABLE : PropertyFlag(0);
656}
657
658static void rna_ksPath_id_type_set(PointerRNA *ptr, int value)
659{
660 KS_Path *data = (KS_Path *)(ptr->data);
661
662 /* set the driver type, then clear the id-block if the type is invalid */
663 data->idtype = value;
664 if ((data->id) && (GS(data->id->name) != data->idtype)) {
665 data->id = nullptr;
666 }
667}
668
669static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value)
670{
671 KS_Path *ksp = (KS_Path *)ptr->data;
672
673 if (ksp->rna_path) {
674 strcpy(value, ksp->rna_path);
675 }
676 else {
677 value[0] = '\0';
678 }
679}
680
681static int rna_ksPath_RnaPath_length(PointerRNA *ptr)
682{
683 KS_Path *ksp = (KS_Path *)ptr->data;
684
685 if (ksp->rna_path) {
686 return strlen(ksp->rna_path);
687 }
688 else {
689 return 0;
690 }
691}
692
693static void rna_ksPath_RnaPath_set(PointerRNA *ptr, const char *value)
694{
695 KS_Path *ksp = (KS_Path *)ptr->data;
696
697 if (ksp->rna_path) {
698 MEM_freeN(ksp->rna_path);
699 }
700
701 if (value[0]) {
702 ksp->rna_path = BLI_strdup(value);
703 }
704 else {
705 ksp->rna_path = nullptr;
706 }
707}
708
709/* ****************************** */
710
711static void rna_KeyingSet_name_set(PointerRNA *ptr, const char *value)
712{
713 KeyingSet *ks = (KeyingSet *)ptr->data;
714
715 /* update names of corresponding groups if name changes */
716 if (!STREQ(ks->name, value)) {
717 KS_Path *ksp;
718
719 for (ksp = static_cast<KS_Path *>(ks->paths.first); ksp; ksp = ksp->next) {
720 if ((ksp->groupmode == KSP_GROUP_KSNAME) && (ksp->id)) {
721 AnimData *adt = BKE_animdata_from_id(ksp->id);
722
723 /* TODO: NLA strips? */
724 /* lazy check - should really find the F-Curve for the affected path and check its
725 * group but this way should be faster and work well for most cases, as long as there
726 * are no conflicts
727 */
729 if (STREQ(ks->name, agrp->name)) {
730 /* there should only be one of these in the action, so can stop... */
731 STRNCPY_UTF8(agrp->name, value);
732 break;
733 }
734 }
735 }
736 }
737 }
738
739 /* finally, update name to new value */
740 STRNCPY(ks->name, value);
741}
742
743static int rna_KeyingSet_active_ksPath_editable(const PointerRNA *ptr, const char ** /*r_info*/)
744{
745 KeyingSet *ks = (KeyingSet *)ptr->data;
746
747 /* only editable if there are some paths to change to */
748 return (BLI_listbase_is_empty(&ks->paths) == false) ? PROP_EDITABLE : PropertyFlag(0);
749}
750
751static PointerRNA rna_KeyingSet_active_ksPath_get(PointerRNA *ptr)
752{
753 KeyingSet *ks = (KeyingSet *)ptr->data;
755 *ptr, &RNA_KeyingSetPath, BLI_findlink(&ks->paths, ks->active_path - 1));
756}
757
758static void rna_KeyingSet_active_ksPath_set(PointerRNA *ptr,
759 PointerRNA value,
760 ReportList * /*reports*/)
761{
762 KeyingSet *ks = (KeyingSet *)ptr->data;
763 KS_Path *ksp = (KS_Path *)value.data;
764 ks->active_path = BLI_findindex(&ks->paths, ksp) + 1;
765}
766
767static int rna_KeyingSet_active_ksPath_index_get(PointerRNA *ptr)
768{
769 KeyingSet *ks = (KeyingSet *)ptr->data;
770 return std::max(ks->active_path - 1, 0);
771}
772
773static void rna_KeyingSet_active_ksPath_index_set(PointerRNA *ptr, int value)
774{
775 KeyingSet *ks = (KeyingSet *)ptr->data;
776 ks->active_path = value + 1;
777}
778
779static void rna_KeyingSet_active_ksPath_index_range(
780 PointerRNA *ptr, int *min, int *max, int * /*softmin*/, int * /*softmax*/)
781{
782 KeyingSet *ks = (KeyingSet *)ptr->data;
783
784 *min = 0;
785 *max = max_ii(0, BLI_listbase_count(&ks->paths) - 1);
786}
787
788static PointerRNA rna_KeyingSet_typeinfo_get(PointerRNA *ptr)
789{
790 KeyingSet *ks = (KeyingSet *)ptr->data;
791 KeyingSetInfo *ksi = nullptr;
792
793 /* keying set info is only for builtin Keying Sets */
794 if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
796 }
797 return RNA_pointer_create_with_parent(*ptr, &RNA_KeyingSetInfo, ksi);
798}
799
800static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset,
801 ReportList *reports,
802 ID *id,
803 const char rna_path[],
804 int index,
805 int group_method,
806 const char group_name[])
807{
808 KS_Path *ksp = nullptr;
809 short flag = 0;
810
811 /* Special case when index = -1, we key the whole array
812 * (as with other places where index is used). */
813 if (index == -1) {
815 index = 0;
816 }
817
818 /* if data is valid, call the API function for this */
819 if (keyingset) {
820 ksp = BKE_keyingset_add_path(keyingset, id, group_name, rna_path, index, flag, group_method);
821 keyingset->active_path = BLI_listbase_count(&keyingset->paths);
822 }
823 else {
824 BKE_report(reports, RPT_ERROR, "Keying set path could not be added");
825 }
826
827 /* return added path */
828 return ksp;
829}
830
831static void rna_KeyingSet_paths_remove(KeyingSet *keyingset,
832 ReportList *reports,
833 PointerRNA *ksp_ptr)
834{
835 KS_Path *ksp = static_cast<KS_Path *>(ksp_ptr->data);
836
837 /* if data is valid, call the API function for this */
838 if ((keyingset && ksp) == false) {
839 BKE_report(reports, RPT_ERROR, "Keying set path could not be removed");
840 return;
841 }
842
843 /* remove the active path from the KeyingSet */
844 BKE_keyingset_free_path(keyingset, ksp);
845 ksp_ptr->invalidate();
846
847 /* the active path number will most likely have changed */
848 /* TODO: we should get more fancy and actually check if it was removed,
849 * but this will do for now */
850 keyingset->active_path = 0;
851}
852
853static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports)
854{
855 /* if data is valid, call the API function for this */
856 if (keyingset) {
857 KS_Path *ksp, *kspn;
858
859 /* free each path as we go to avoid looping twice */
860 for (ksp = static_cast<KS_Path *>(keyingset->paths.first); ksp; ksp = kspn) {
861 kspn = ksp->next;
862 BKE_keyingset_free_path(keyingset, ksp);
863 }
864
865 /* reset the active path, since there aren't any left */
866 keyingset->active_path = 0;
867 }
868 else {
869 BKE_report(reports, RPT_ERROR, "Keying set paths could not be removed");
870 }
871}
872
873/* needs wrapper function to push notifier */
874static NlaTrack *rna_NlaTrack_new(ID *id, AnimData *adt, Main *bmain, bContext *C, NlaTrack *track)
875{
876 NlaTrack *new_track;
877
878 if (track == nullptr) {
880 }
881 else {
882 new_track = BKE_nlatrack_new_after(&adt->nla_tracks, track, ID_IS_OVERRIDE_LIBRARY(id));
883 }
884
885 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
886
888
891
892 return new_track;
893}
894
895static void rna_NlaTrack_remove(
896 ID *id, AnimData *adt, Main *bmain, bContext *C, ReportList *reports, PointerRNA *track_ptr)
897{
898 NlaTrack *track = static_cast<NlaTrack *>(track_ptr->data);
899
900 if (BLI_findindex(&adt->nla_tracks, track) == -1) {
901 BKE_reportf(reports, RPT_ERROR, "NlaTrack '%s' cannot be removed", track->name);
902 return;
903 }
904
905 BKE_nlatrack_remove_and_free(&adt->nla_tracks, track, true);
906 track_ptr->invalidate();
907
909
912}
913
914static PointerRNA rna_NlaTrack_active_get(PointerRNA *ptr)
915{
916 AnimData *adt = (AnimData *)ptr->data;
918 return RNA_pointer_create_with_parent(*ptr, &RNA_NlaTrack, track);
919}
920
921static void rna_NlaTrack_active_set(PointerRNA *ptr, PointerRNA value, ReportList * /*reports*/)
922{
923 AnimData *adt = (AnimData *)ptr->data;
924 NlaTrack *track = (NlaTrack *)value.data;
926}
927
928static FCurve *rna_Driver_from_existing(AnimData *adt, bContext *C, FCurve *src_driver)
929{
930 /* verify that we've got a driver to duplicate */
931 if (ELEM(nullptr, src_driver, src_driver->driver)) {
932 BKE_report(CTX_wm_reports(C), RPT_ERROR, "No valid driver data to create copy of");
933 return nullptr;
934 }
935 else {
936 /* just make a copy of the existing one and add to self */
937 FCurve *new_fcu = BKE_fcurve_copy(src_driver);
938
939 /* XXX: if we impose any ordering on these someday, this will be problematic */
940 BLI_addtail(&adt->drivers, new_fcu);
941 return new_fcu;
942 }
943}
944
945static FCurve *rna_Driver_new(
946 ID *id, AnimData *adt, Main *bmain, ReportList *reports, const char *rna_path, int array_index)
947{
948 if (rna_path[0] == '\0') {
949 BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument");
950 return nullptr;
951 }
952
953 if (BKE_fcurve_find(&adt->drivers, rna_path, array_index)) {
954 BKE_reportf(reports, RPT_ERROR, "Driver '%s[%d]' already exists", rna_path, array_index);
955 return nullptr;
956 }
957
958 FCurve *fcu = verify_driver_fcurve(id, rna_path, array_index, DRIVER_FCURVE_KEYFRAMES);
959 BLI_assert(fcu != nullptr);
960
962
963 return fcu;
964}
965
966static void rna_Driver_remove(AnimData *adt, Main *bmain, ReportList *reports, FCurve *fcu)
967{
968 if (!BLI_remlink_safe(&adt->drivers, fcu)) {
969 BKE_report(reports, RPT_ERROR, "Driver not found in this animation data");
970 return;
971 }
972 BKE_fcurve_free(fcu);
974}
975
976static FCurve *rna_Driver_find(AnimData *adt,
977 ReportList *reports,
978 const char *data_path,
979 int index)
980{
981 if (data_path[0] == '\0') {
982 BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument");
983 return nullptr;
984 }
985
986 /* Returns nullptr if not found. */
987 return BKE_fcurve_find(&adt->drivers, data_path, index);
988}
989
990std::optional<std::string> rna_AnimData_path(const PointerRNA * /*ptr*/)
991{
992 return std::string{"animation_data"};
993}
994
996{
997 PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
998 PointerRNA *ptr_src = &rnaapply_ctx.ptr_src;
999 PointerRNA *ptr_storage = &rnaapply_ctx.ptr_storage;
1000 PropertyRNA *prop_dst = rnaapply_ctx.prop_dst;
1001 PropertyRNA *prop_src = rnaapply_ctx.prop_src;
1002 const int len_dst = rnaapply_ctx.len_src;
1003 const int len_src = rnaapply_ctx.len_src;
1004 const int len_storage = rnaapply_ctx.len_storage;
1006
1007 BLI_assert(len_dst == len_src && (!ptr_storage || len_dst == len_storage) && len_dst == 0);
1009 "Unsupported RNA override operation on animdata pointer");
1010 UNUSED_VARS_NDEBUG(ptr_storage, len_dst, len_src, len_storage, opop);
1011
1012 /* AnimData is a special case, since you cannot edit/replace it, it's either existent or not.
1013 * Further more, when an animdata is added to the linked reference later on, the one created
1014 * for the liboverride needs to be 'merged', such that its overridable data is kept. */
1015 AnimData *adt_dst = static_cast<AnimData *>(RNA_property_pointer_get(ptr_dst, prop_dst).data);
1016 AnimData *adt_src = static_cast<AnimData *>(RNA_property_pointer_get(ptr_src, prop_src).data);
1017
1018 if (adt_dst == nullptr && adt_src != nullptr) {
1019 /* Copy anim data from reference into final local ID. */
1020 BKE_animdata_copy_id(nullptr, ptr_dst->owner_id, ptr_src->owner_id, 0);
1021 RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
1022 return true;
1023 }
1024 else if (adt_dst != nullptr && adt_src == nullptr) {
1025 /* Override has cleared/removed anim data from its reference. */
1026 BKE_animdata_free(ptr_dst->owner_id, true);
1027 RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
1028 return true;
1029 }
1030 else if (adt_dst != nullptr && adt_src != nullptr) {
1031 /* Override had to create an anim data, but now its reference also has one, need to merge
1032 * them by keeping the few overridable data from the liboverride, while using the animdata of
1033 * the reference.
1034 *
1035 * Note that this case will not be encountered when the linked reference data already had
1036 * anim data, since there will be no operation for the animdata pointer itself then, only
1037 * potentially for its internal overridable data (NLA, action...). */
1038 id_us_min(reinterpret_cast<ID *>(adt_dst->action));
1039 adt_dst->action = adt_src->action;
1040 id_us_plus(reinterpret_cast<ID *>(adt_dst->action));
1041 id_us_min(reinterpret_cast<ID *>(adt_dst->tmpact));
1042
1043 adt_dst->slot_handle = adt_src->slot_handle;
1044 adt_dst->tmp_slot_handle = adt_src->tmp_slot_handle;
1047 adt_dst->tmpact = adt_src->tmpact;
1048 id_us_plus(reinterpret_cast<ID *>(adt_dst->tmpact));
1049 adt_dst->act_blendmode = adt_src->act_blendmode;
1050 adt_dst->act_extendmode = adt_src->act_extendmode;
1051 adt_dst->act_influence = adt_src->act_influence;
1052 adt_dst->flag = adt_src->flag;
1053
1054 /* NLA tracks: since overrides are always after tracks from linked reference, we can 'just'
1055 * move the whole list from `src` to the end of the list of `dst` (which currently contains
1056 * tracks from linked reference). then active track and strip pointers can be kept as-is. */
1057 BLI_movelisttolist(&adt_dst->nla_tracks, &adt_src->nla_tracks);
1058 adt_dst->act_track = adt_src->act_track;
1059 adt_dst->actstrip = adt_src->actstrip;
1060
1062 ANIM_id_update(bmain, ptr_dst->owner_id);
1063 }
1064
1065 return false;
1066}
1067
1068bool rna_NLA_tracks_override_apply(Main *bmain, RNAPropertyOverrideApplyContext &rnaapply_ctx)
1069{
1070 PointerRNA *ptr_dst = &rnaapply_ctx.ptr_dst;
1071 PointerRNA *ptr_src = &rnaapply_ctx.ptr_src;
1072 PropertyRNA *prop_dst = rnaapply_ctx.prop_dst;
1074
1076 "Unsupported RNA override operation on constraints collection");
1077
1078 AnimData *anim_data_dst = (AnimData *)ptr_dst->data;
1079 AnimData *anim_data_src = (AnimData *)ptr_src->data;
1080
1081 /* Remember that insertion operations are defined and stored in correct order, which means that
1082 * even if we insert several items in a row, we always insert first one, then second one, etc.
1083 * So we should always find 'anchor' track in both _src *and* _dst.
1084 *
1085 * This is only true however is NLA tracks do not get removed from linked data. Otherwise, an
1086 * index-based reference may lead to lost data. */
1087 NlaTrack *nla_track_anchor = nullptr;
1088# if 0
1089 /* This is not working so well with index-based insertion, especially in case some tracks get
1090 * added to lib linked data. So we simply add locale tracks at the end of the list always, order
1091 * of override operations should ensure order of local tracks is preserved properly. */
1092 if (opop->subitem_reference_index >= 0) {
1093 nla_track_anchor = BLI_findlink(&anim_data_dst->nla_tracks, opop->subitem_reference_index);
1094 }
1095 /* Otherwise we just insert in first position. */
1096# else
1097 nla_track_anchor = static_cast<NlaTrack *>(anim_data_dst->nla_tracks.last);
1098# endif
1099
1100 NlaTrack *nla_track_src = nullptr;
1101 if (opop->subitem_local_index >= 0) {
1102 nla_track_src = static_cast<NlaTrack *>(
1103 BLI_findlink(&anim_data_src->nla_tracks, opop->subitem_local_index));
1104 }
1105
1106 if (nla_track_src == nullptr) {
1107 /* Can happen if tracks were removed from linked data. */
1108 return false;
1109 }
1110
1111 NlaTrack *nla_track_dst = BKE_nlatrack_copy(bmain, nla_track_src, true, 0);
1112
1113 /* This handles nullptr anchor as expected by adding at head of list. */
1114 BLI_insertlinkafter(&anim_data_dst->nla_tracks, nla_track_anchor, nla_track_dst);
1115
1116 // printf("%s: We inserted a NLA Track...\n", __func__);
1117
1118 RNA_property_update_main(bmain, nullptr, ptr_dst, prop_dst);
1119 return true;
1120}
1121
1122#else
1123
1124/* helper function for Keying Set -> keying settings */
1125static void rna_def_common_keying_flags(StructRNA *srna, short reg)
1126{
1127 PropertyRNA *prop;
1128
1129 /* override scene/userpref defaults? */
1130 prop = RNA_def_property(srna, "use_insertkey_override_needed", PROP_BOOLEAN, PROP_NONE);
1131 RNA_def_property_boolean_sdna(prop, nullptr, "keyingoverride", INSERTKEY_NEEDED);
1133 "Override Insert Keyframes Default- Only Needed",
1134 "Override default setting to only insert keyframes where they're "
1135 "needed in the relevant F-Curves");
1136 if (reg) {
1138 }
1139
1140 prop = RNA_def_property(srna, "use_insertkey_override_visual", PROP_BOOLEAN, PROP_NONE);
1141 RNA_def_property_boolean_sdna(prop, nullptr, "keyingoverride", INSERTKEY_MATRIX);
1143 prop,
1144 "Override Insert Keyframes Default - Visual",
1145 "Override default setting to insert keyframes based on 'visual transforms'");
1146 if (reg) {
1148 }
1149
1150 /* value to override defaults with */
1151 prop = RNA_def_property(srna, "use_insertkey_needed", PROP_BOOLEAN, PROP_NONE);
1152 RNA_def_property_boolean_sdna(prop, nullptr, "keyingflag", INSERTKEY_NEEDED);
1154 "Insert Keyframes - Only Needed",
1155 "Only insert keyframes where they're needed in the relevant F-Curves");
1156 if (reg) {
1158 }
1159
1160 prop = RNA_def_property(srna, "use_insertkey_visual", PROP_BOOLEAN, PROP_NONE);
1161 RNA_def_property_boolean_sdna(prop, nullptr, "keyingflag", INSERTKEY_MATRIX);
1163 prop, "Insert Keyframes - Visual", "Insert keyframes based on 'visual transforms'");
1164 if (reg) {
1166 }
1167}
1168
1169/* --- */
1170
1171/* To avoid repeating it twice! */
1172# define KEYINGSET_IDNAME_DOC \
1173 "If this is set, the Keying Set gets a custom ID, otherwise it takes " \
1174 "the name of the class used to define the Keying Set (for example, " \
1175 "if the class name is \"BUILTIN_KSI_location\", and bl_idname is not " \
1176 "set by the script, then bl_idname = \"BUILTIN_KSI_location\")"
1177
1179{
1180 StructRNA *srna;
1181 PropertyRNA *prop;
1182 FunctionRNA *func;
1183 PropertyRNA *parm;
1184
1185 srna = RNA_def_struct(brna, "KeyingSetInfo", nullptr);
1186 RNA_def_struct_sdna(srna, "KeyingSetInfo");
1188 srna, "Keying Set Info", "Callback function defines for builtin Keying Sets");
1189 RNA_def_struct_refine_func(srna, "rna_KeyingSetInfo_refine");
1191 srna, "rna_KeyingSetInfo_register", "rna_KeyingSetInfo_unregister", nullptr);
1192
1193 /* Properties --------------------- */
1194
1195 RNA_define_verify_sdna(false); /* not in sdna */
1196
1197 prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1198 RNA_def_property_string_sdna(prop, nullptr, "idname");
1201
1202 prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
1203 RNA_def_property_string_sdna(prop, nullptr, "name");
1204 RNA_def_property_ui_text(prop, "UI Name", "");
1205 RNA_def_struct_name_property(srna, prop);
1207
1208 prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
1209 RNA_def_property_string_sdna(prop, nullptr, "description");
1210 RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
1212 RNA_def_property_ui_text(prop, "Description", "A short description of the keying set");
1213
1214 /* Regarding why we don't use rna_def_common_keying_flags() here:
1215 * - Using it would keep this case in sync with the other places
1216 * where these options are exposed (which are optimized for being
1217 * used in the UI).
1218 * - Unlike all the other places, this case is used for defining
1219 * new "built in" Keying Sets via the Python API. In that case,
1220 * it makes more sense to expose these in a way more similar to
1221 * other places featuring bl_idname/label/description (i.e. operators)
1222 */
1223 prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
1225 RNA_def_property_enum_sdna(prop, nullptr, "keyingflag");
1227 RNA_def_property_ui_text(prop, "Options", "Keying Set options to use when inserting keyframes");
1228
1230
1231 /* Function Callbacks ------------- */
1232 /* poll */
1233 func = RNA_def_function(srna, "poll", nullptr);
1234 RNA_def_function_ui_description(func, "Test if Keying Set can be used or not");
1236 RNA_def_function_return(func, RNA_def_boolean(func, "ok", true, "", ""));
1237 parm = RNA_def_pointer(func, "context", "Context", "", "");
1239
1240 /* iterator */
1241 func = RNA_def_function(srna, "iterator", nullptr);
1243 func, "Call generate() on the structs which have properties to be keyframed");
1245 parm = RNA_def_pointer(func, "context", "Context", "", "");
1247 parm = RNA_def_pointer(func, "ks", "KeyingSet", "", "");
1249
1250 /* generate */
1251 func = RNA_def_function(srna, "generate", nullptr);
1253 func, "Add Paths to the Keying Set to keyframe the properties of the given data");
1255 parm = RNA_def_pointer(func, "context", "Context", "", "");
1257 parm = RNA_def_pointer(func, "ks", "KeyingSet", "", "");
1259 parm = RNA_def_pointer(func, "data", "AnyType", "", "");
1261}
1262
1264{
1265 StructRNA *srna;
1266 PropertyRNA *prop;
1267
1268 srna = RNA_def_struct(brna, "KeyingSetPath", nullptr);
1269 RNA_def_struct_sdna(srna, "KS_Path");
1270 RNA_def_struct_ui_text(srna, "Keying Set Path", "Path to a setting for use in a Keying Set");
1271
1272 /* ID */
1273 prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
1274 RNA_def_property_struct_type(prop, "ID");
1276 RNA_def_property_editable_func(prop, "rna_ksPath_id_editable");
1277 RNA_def_property_pointer_funcs(prop, nullptr, nullptr, "rna_ksPath_id_typef", nullptr);
1279 "ID-Block",
1280 "ID-Block that keyframes for Keying Set should be added to "
1281 "(for Absolute Keying Sets only)");
1283 prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, nullptr); /* XXX: maybe a bit too noisy */
1284
1285 prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
1286 RNA_def_property_enum_sdna(prop, nullptr, "idtype");
1289 RNA_def_property_enum_funcs(prop, nullptr, "rna_ksPath_id_type_set", nullptr);
1290 RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used");
1293 prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, nullptr); /* XXX: maybe a bit too noisy */
1294
1295 /* Group */
1296 prop = RNA_def_property(srna, "group", PROP_STRING, PROP_NONE);
1298 prop, "Group Name", "Name of Action Group to assign setting(s) for this path to");
1300 prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, nullptr); /* XXX: maybe a bit too noisy */
1301
1302 /* Grouping */
1303 prop = RNA_def_property(srna, "group_method", PROP_ENUM, PROP_NONE);
1304 RNA_def_property_enum_sdna(prop, nullptr, "groupmode");
1307 prop, "Grouping Method", "Method used to define which Group-name to use");
1309 prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, nullptr); /* XXX: maybe a bit too noisy */
1310
1311 /* Path + Array Index */
1312 prop = RNA_def_property(srna, "data_path", PROP_STRING, PROP_NONE);
1314 prop, "rna_ksPath_RnaPath_get", "rna_ksPath_RnaPath_length", "rna_ksPath_RnaPath_set");
1315 RNA_def_property_ui_text(prop, "Data Path", "Path to property setting");
1316 RNA_def_struct_name_property(srna, prop); /* XXX this is the best indicator for now... */
1318
1319 /* called 'index' when given as function arg */
1320 prop = RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE);
1321 RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific setting if applicable");
1323 prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, nullptr); /* XXX: maybe a bit too noisy */
1324
1325 /* Flags */
1326 prop = RNA_def_property(srna, "use_entire_array", PROP_BOOLEAN, PROP_NONE);
1329 prop,
1330 "Entire Array",
1331 "When an 'array/vector' type is chosen (Location, Rotation, Color, etc.), "
1332 "entire array is to be used");
1334 prop, NC_SCENE | ND_KEYINGSET | NA_EDITED, nullptr); /* XXX: maybe a bit too noisy */
1335
1336 /* Keyframing Settings */
1338}
1339
1340/* keyingset.paths */
1342{
1343 StructRNA *srna;
1344
1345 FunctionRNA *func;
1346 PropertyRNA *parm;
1347
1348 PropertyRNA *prop;
1349
1350 RNA_def_property_srna(cprop, "KeyingSetPaths");
1351 srna = RNA_def_struct(brna, "KeyingSetPaths", nullptr);
1352 RNA_def_struct_sdna(srna, "KeyingSet");
1353 RNA_def_struct_ui_text(srna, "Keying set paths", "Collection of keying set paths");
1354
1355 /* Add Path */
1356 func = RNA_def_function(srna, "add", "rna_KeyingSet_paths_add");
1357 RNA_def_function_ui_description(func, "Add a new path for the Keying Set");
1359 /* return arg */
1360 parm = RNA_def_pointer(
1361 func, "ksp", "KeyingSetPath", "New Path", "Path created and added to the Keying Set");
1362 RNA_def_function_return(func, parm);
1363 /* ID-block for target */
1364 parm = RNA_def_pointer(
1365 func, "target_id", "ID", "Target ID", "ID data-block for the destination");
1367 /* rna-path */
1368 /* XXX hopefully this is long enough */
1369 parm = RNA_def_string(
1370 func, "data_path", nullptr, 256, "Data-Path", "RNA-Path to destination property");
1372 /* index (defaults to -1 for entire array) */
1373 RNA_def_int(func,
1374 "index",
1375 -1,
1376 -1,
1377 INT_MAX,
1378 "Index",
1379 "The index of the destination property (i.e. axis of Location/Rotation/etc.), "
1380 "or -1 for the entire array",
1381 0,
1382 INT_MAX);
1383 /* grouping */
1384 RNA_def_enum(func,
1385 "group_method",
1388 "Grouping Method",
1389 "Method used to define which Group-name to use");
1391 func,
1392 "group_name",
1393 nullptr,
1394 64,
1395 "Group Name",
1396 "Name of Action Group to assign destination to (only if grouping mode is to use this name)");
1397
1398 /* Remove Path */
1399 func = RNA_def_function(srna, "remove", "rna_KeyingSet_paths_remove");
1400 RNA_def_function_ui_description(func, "Remove the given path from the Keying Set");
1402 /* path to remove */
1403 parm = RNA_def_pointer(func, "path", "KeyingSetPath", "Path", "");
1406
1407 /* Remove All Paths */
1408 func = RNA_def_function(srna, "clear", "rna_KeyingSet_paths_clear");
1409 RNA_def_function_ui_description(func, "Remove all the paths from the Keying Set");
1411
1412 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1413 RNA_def_property_struct_type(prop, "KeyingSetPath");
1415 RNA_def_property_editable_func(prop, "rna_KeyingSet_active_ksPath_editable");
1417 "rna_KeyingSet_active_ksPath_get",
1418 "rna_KeyingSet_active_ksPath_set",
1419 nullptr,
1420 nullptr);
1422 prop, "Active Keying Set", "Active Keying Set used to insert/delete keyframes");
1423
1424 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_NONE);
1425 RNA_def_property_int_sdna(prop, nullptr, "active_path");
1427 "rna_KeyingSet_active_ksPath_index_get",
1428 "rna_KeyingSet_active_ksPath_index_set",
1429 "rna_KeyingSet_active_ksPath_index_range");
1430 RNA_def_property_ui_text(prop, "Active Path Index", "Current Keying Set index");
1431}
1432
1434{
1435 StructRNA *srna;
1436 PropertyRNA *prop;
1437
1438 srna = RNA_def_struct(brna, "KeyingSet", nullptr);
1439 RNA_def_struct_ui_text(srna, "Keying Set", "Settings that should be keyframed together");
1440
1441 /* Id/Label */
1442 prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
1443 RNA_def_property_string_sdna(prop, nullptr, "idname");
1446 /* NOTE: disabled, as ID name shouldn't be editable */
1447# if 0
1449# endif
1450
1451 prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
1452 RNA_def_property_string_sdna(prop, nullptr, "name");
1453 RNA_def_property_string_funcs(prop, nullptr, nullptr, "rna_KeyingSet_name_set");
1454 RNA_def_property_ui_text(prop, "UI Name", "");
1455 RNA_def_struct_ui_icon(srna, ICON_KEYINGSET);
1456 RNA_def_struct_name_property(srna, prop);
1458
1459 prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
1460 RNA_def_property_string_sdna(prop, nullptr, "description");
1461 RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
1462 RNA_def_property_ui_text(prop, "Description", "A short description of the keying set");
1463
1464 /* KeyingSetInfo (Type Info) for Builtin Sets only. */
1465 prop = RNA_def_property(srna, "type_info", PROP_POINTER, PROP_NONE);
1466 RNA_def_property_struct_type(prop, "KeyingSetInfo");
1467 RNA_def_property_pointer_funcs(prop, "rna_KeyingSet_typeinfo_get", nullptr, nullptr, nullptr);
1469 prop, "Type Info", "Callback function defines for built-in Keying Sets");
1470
1471 /* Paths */
1472 prop = RNA_def_property(srna, "paths", PROP_COLLECTION, PROP_NONE);
1473 RNA_def_property_collection_sdna(prop, nullptr, "paths", nullptr);
1474 RNA_def_property_struct_type(prop, "KeyingSetPath");
1476 prop, "Paths", "Keying Set Paths to define settings that get keyframed together");
1477 rna_def_keyingset_paths(brna, prop);
1478
1479 /* Flags */
1480 prop = RNA_def_property(srna, "is_path_absolute", PROP_BOOLEAN, PROP_NONE);
1482 RNA_def_property_boolean_sdna(prop, nullptr, "flag", KEYINGSET_ABSOLUTE);
1484 "Absolute",
1485 "Keying Set defines specific paths/settings to be keyframed "
1486 "(i.e. is not reliant on context info)");
1487
1488 /* Keyframing Flags */
1490
1491 /* Keying Set API */
1492 RNA_api_keyingset(srna);
1493}
1494
1495# undef KEYINGSET_IDNAME_DOC
1496/* --- */
1497
1499{
1500 StructRNA *srna;
1501 PropertyRNA *parm;
1502 FunctionRNA *func;
1503
1504 PropertyRNA *prop;
1505
1506 RNA_def_property_srna(cprop, "NlaTracks");
1507 srna = RNA_def_struct(brna, "NlaTracks", nullptr);
1508 RNA_def_struct_sdna(srna, "AnimData");
1509 RNA_def_struct_ui_text(srna, "NLA Tracks", "Collection of NLA Tracks");
1510
1511 func = RNA_def_function(srna, "new", "rna_NlaTrack_new");
1513 RNA_def_function_ui_description(func, "Add a new NLA Track");
1514 RNA_def_pointer(func, "prev", "NlaTrack", "", "NLA Track to add the new one after");
1515 /* return type */
1516 parm = RNA_def_pointer(func, "track", "NlaTrack", "", "New NLA Track");
1517 RNA_def_function_return(func, parm);
1518
1519 func = RNA_def_function(srna, "remove", "rna_NlaTrack_remove");
1522 RNA_def_function_ui_description(func, "Remove a NLA Track");
1523 parm = RNA_def_pointer(func, "track", "NlaTrack", "", "NLA Track to remove");
1526
1527 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1528 RNA_def_property_struct_type(prop, "NlaTrack");
1530 prop, "rna_NlaTrack_active_get", "rna_NlaTrack_active_set", nullptr, nullptr);
1532 RNA_def_property_ui_text(prop, "Active Track", "Active NLA Track");
1534 /* XXX: should (but doesn't) update the active track in the NLA window */
1536}
1537
1539{
1540 StructRNA *srna;
1541 PropertyRNA *parm;
1542 FunctionRNA *func;
1543
1544 // PropertyRNA *prop;
1545
1546 RNA_def_property_srna(cprop, "AnimDataDrivers");
1547 srna = RNA_def_struct(brna, "AnimDataDrivers", nullptr);
1548 RNA_def_struct_sdna(srna, "AnimData");
1549 RNA_def_struct_ui_text(srna, "Drivers", "Collection of Driver F-Curves");
1550
1551 /* Match: ActionFCurves.new/remove */
1552
1553 /* AnimData.drivers.new(...) */
1554 func = RNA_def_function(srna, "new", "rna_Driver_new");
1556 parm = RNA_def_string(func, "data_path", nullptr, 0, "Data Path", "F-Curve data path to use");
1558 RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Array index", 0, INT_MAX);
1559 /* return type */
1560 parm = RNA_def_pointer(func, "driver", "FCurve", "", "Newly Driver F-Curve");
1561 RNA_def_function_return(func, parm);
1562
1563 /* AnimData.drivers.remove(...) */
1564 func = RNA_def_function(srna, "remove", "rna_Driver_remove");
1566 parm = RNA_def_pointer(func, "driver", "FCurve", "", "");
1568
1569 /* AnimData.drivers.from_existing(...) */
1570 func = RNA_def_function(srna, "from_existing", "rna_Driver_from_existing");
1572 RNA_def_function_ui_description(func, "Add a new driver given an existing one");
1573 RNA_def_pointer(func,
1574 "src_driver",
1575 "FCurve",
1576 "",
1577 "Existing Driver F-Curve to use as template for a new one");
1578 /* return type */
1579 parm = RNA_def_pointer(func, "driver", "FCurve", "", "New Driver F-Curve");
1580 RNA_def_function_return(func, parm);
1581
1582 /* AnimData.drivers.find(...) */
1583 func = RNA_def_function(srna, "find", "rna_Driver_find");
1585 func,
1586 "Find a driver F-Curve. Note that this function performs a linear scan "
1587 "of all driver F-Curves.");
1589 parm = RNA_def_string(func, "data_path", nullptr, 0, "Data Path", "F-Curve data path");
1591 RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Array index", 0, INT_MAX);
1592 /* return type */
1593 parm = RNA_def_pointer(
1594 func, "fcurve", "FCurve", "", "The found F-Curve, or None if it doesn't exist");
1595 RNA_def_function_return(func, parm);
1596}
1597
1599{
1600 PropertyRNA *prop;
1601
1602 prop = RNA_def_property(srna, "animation_data", PROP_POINTER, PROP_NONE);
1603 RNA_def_property_pointer_sdna(prop, nullptr, "adt");
1606 RNA_def_property_override_funcs(prop, nullptr, nullptr, "rna_AnimaData_override_apply");
1607 RNA_def_property_ui_text(prop, "Animation Data", "Animation data for this data-block");
1608}
1609
1611{
1612 StructRNA *srna;
1613 PropertyRNA *prop;
1614
1615 srna = RNA_def_struct(brna, "AnimData", nullptr);
1616 RNA_def_struct_ui_text(srna, "Animation Data", "Animation data for data-block");
1617 RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA);
1618 RNA_def_struct_path_func(srna, "rna_AnimData_path");
1619
1620 /* NLA */
1621 prop = RNA_def_property(srna, "nla_tracks", PROP_COLLECTION, PROP_NONE);
1622 RNA_def_property_collection_sdna(prop, nullptr, "nla_tracks", nullptr);
1623 RNA_def_property_struct_type(prop, "NlaTrack");
1624 RNA_def_property_ui_text(prop, "NLA Tracks", "NLA Tracks (i.e. Animation Layers)");
1628 RNA_def_property_override_funcs(prop, nullptr, nullptr, "rna_NLA_tracks_override_apply");
1629
1630 rna_api_animdata_nla_tracks(brna, prop);
1631
1633
1634 /* Active Action */
1635 prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
1636 RNA_def_property_struct_type(prop, "Action");
1637 /* this flag as well as the dynamic test must be defined for this to be editable... */
1641 prop,
1642 /* Define a getter that is NULL-safe, so that an RNA_AnimData prop with `ptr->data = nullptr`
1643 * can still be used to get the property. In that case it will always return nullptr, of
1644 * course, but it won't crash Blender. */
1645 "rna_AnimData_action_get",
1646 /* Similarly, for the setter, the NULL-safety allows constructing the AnimData struct on
1647 * assignment of this "action" property. This is possible because RNA has typed NULL
1648 * pointers, and thus it knows which setter to call even when `ptr->data` is NULL. */
1649 "rna_AnimData_action_set",
1650 nullptr,
1651 "rna_Action_id_poll");
1652 RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
1653 RNA_def_property_ui_text(prop, "Action", "Active Action for this data-block");
1654 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
1655
1656 /* Active Action Settings */
1657 prop = RNA_def_property(srna, "action_extrapolation", PROP_ENUM, PROP_NONE);
1658 RNA_def_property_enum_sdna(prop, nullptr, "act_extendmode");
1661 prop,
1662 "Action Extrapolation",
1663 "Action to take for gaps past the Active Action's range (when evaluating with NLA)");
1664 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update");
1665
1666 prop = RNA_def_property(srna, "action_blend_type", PROP_ENUM, PROP_NONE);
1667 RNA_def_property_enum_sdna(prop, nullptr, "act_blendmode");
1670 prop,
1671 "Action Blending",
1672 "Method used for combining Active Action's result with result of NLA stack");
1673 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update"); /* this will do? */
1674
1675 prop = RNA_def_property(srna, "action_influence", PROP_FLOAT, PROP_FACTOR);
1676 RNA_def_property_float_sdna(prop, nullptr, "act_influence");
1678 RNA_def_property_range(prop, 0.0f, 1.0f);
1680 "Action Influence",
1681 "Amount the Active Action contributes to the result of the NLA stack");
1682 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update"); /* this will do? */
1683
1684 /* Temporary action slot for tweak mode. */
1685 prop = RNA_def_property(srna, "action_tweak_storage", PROP_POINTER, PROP_NONE);
1686 RNA_def_property_pointer_sdna(prop, nullptr, "tmpact");
1689 prop, nullptr, "rna_AnimData_tmpact_set", nullptr, "rna_Action_id_poll");
1691 "Tweak Mode Action Storage",
1692 "Storage to temporarily hold the main action while in tweak mode");
1693 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
1694
1695 /* Temporary action slot for tweak mode. Just like `action_slot_handle` this is needed for
1696 * library overrides to work. */
1697 prop = RNA_def_property(srna, "action_slot_handle_tweak_storage", PROP_INT, PROP_NONE);
1698 RNA_def_property_int_sdna(prop, nullptr, "tmp_slot_handle");
1701 "Tweak Mode Action Slot Storage",
1702 "Storage to temporarily hold the main action slot while in tweak mode");
1703 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
1704
1705 /* Drivers */
1706 prop = RNA_def_property(srna, "drivers", PROP_COLLECTION, PROP_NONE);
1707 RNA_def_property_collection_sdna(prop, nullptr, "drivers", nullptr);
1708 RNA_def_property_struct_type(prop, "FCurve");
1709 RNA_def_property_ui_text(prop, "Drivers", "The Drivers/Expressions for this data-block");
1710
1712
1713 rna_api_animdata_drivers(brna, prop);
1714
1716
1717 /* General Settings */
1718 prop = RNA_def_property(srna, "use_nla", PROP_BOOLEAN, PROP_NONE);
1721 prop, "NLA Evaluation Enabled", "NLA stack is evaluated when evaluating this block");
1722 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update"); /* this will do? */
1723
1724 prop = RNA_def_property(srna, "use_tweak_mode", PROP_BOOLEAN, PROP_NONE);
1725 RNA_def_property_boolean_sdna(prop, nullptr, "flag", ADT_NLA_EDIT_ON);
1726 RNA_def_property_boolean_funcs(prop, nullptr, "rna_AnimData_tweakmode_set");
1728 prop, "Use NLA Tweak Mode", "Whether to enable or disable tweak mode in NLA");
1729 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, "rna_AnimData_update");
1730 RNA_def_property_override_funcs(prop, nullptr, nullptr, "rna_AnimData_tweakmode_override_apply");
1731
1732 prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
1735 RNA_def_property_ui_text(prop, "Pin in Graph Editor", "");
1737
1738 /* This property is not necessary for the Python API (that is better off using
1739 * slot references/pointers directly), but it is needed for library overrides
1740 * to work. */
1741 prop = RNA_def_property(srna, "action_slot_handle", PROP_INT, PROP_NONE);
1742 RNA_def_property_int_sdna(prop, nullptr, "slot_handle");
1743 RNA_def_property_int_funcs(prop, nullptr, "rna_AnimData_action_slot_handle_set", nullptr);
1745 "Action Slot Handle",
1746 "A number that identifies which sub-set of the Action is considered "
1747 "to be for this data-block");
1750 prop, "rna_AnimData_slot_handle_override_diff", nullptr, nullptr);
1751 RNA_def_property_update(prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_dependency_update");
1752
1753 prop = RNA_def_property(srna, "last_slot_identifier", PROP_STRING, PROP_NONE);
1754 RNA_def_property_string_sdna(prop, nullptr, "last_slot_identifier");
1756 prop,
1757 "Last Action Slot Identifier",
1758 "The identifier of the most recently assigned action slot. The slot identifies which "
1759 "sub-set of the Action is considered to be for this data-block, and its identifier is used "
1760 "to find the right slot when assigning an Action.");
1761
1762 prop = RNA_def_property(srna, "action_slot", PROP_POINTER, PROP_NONE);
1763 RNA_def_property_struct_type(prop, "ActionSlot");
1767 prop,
1768 "Action Slot",
1769 "The slot identifies which sub-set of the Action is considered to be for this "
1770 "data-block, and its name is used to find the right slot when assigning an Action");
1772 prop, "rna_AnimData_action_slot_get", "rna_AnimData_action_slot_set", nullptr, nullptr);
1774 prop, NC_ANIMATION | ND_NLA_ACTCHANGE, "rna_AnimData_action_slot_update");
1775 /* `adt.action_slot` is exposed to RNA as a pointer for things like the action slot selector in
1776 * the GUI. The ground truth of the assigned slot, however, is `action_slot_handle` declared
1777 * above. That property is used for library override operations, and this pointer property should
1778 * just be ignored.
1779 *
1780 * This needs PROPOVERRIDE_IGNORE; PROPOVERRIDE_NO_COMPARISON is not suitable here. This property
1781 * should act as if it is an overridable property (as from the user's perspective, it is), but an
1782 * override operation should not be created for it. It will be created for `action_slot_handle`,
1783 * and that's enough. */
1785
1786 prop = RNA_def_property(srna, "action_suitable_slots", PROP_COLLECTION, PROP_NONE);
1787 RNA_def_property_struct_type(prop, "ActionSlot");
1789 "rna_iterator_animdata_action_suitable_slots_begin",
1790 "rna_iterator_array_next",
1791 "rna_iterator_array_end",
1792 "rna_iterator_array_dereference_get",
1793 nullptr,
1794 nullptr,
1795 nullptr,
1796 nullptr);
1797 RNA_def_property_ui_text(prop, "Slots", "The list of slots in this animation data-block");
1798
1800
1801 /* Animation Data API */
1802 RNA_api_animdata(srna);
1803}
1804
1805/* --- */
1806
1808{
1809 rna_def_animdata(brna);
1810
1811 rna_def_keyingset(brna);
1814}
1815
1816#endif
Functions and classes to work with Actions.
Functions for backward compatibility with the legacy Action API.
Functionality to interact with keying sets.
bool BKE_animdata_action_editable(const AnimData *adt)
Definition anim_data.cc:151
bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, int flag)
Definition anim_data.cc:369
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
void BKE_animdata_free(ID *id, bool do_id_user)
Definition anim_data.cc:188
struct KS_Path * BKE_keyingset_add_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode)
Definition anim_sys.cc:164
void BKE_keyingset_free_path(struct KeyingSet *ks, struct KS_Path *ksp)
Definition anim_sys.cc:227
ReportList * CTX_wm_reports(const bContext *C)
FCurve * BKE_fcurve_copy(const FCurve *fcu)
FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
void BKE_fcurve_free(FCurve *fcu)
void id_us_plus(ID *id)
Definition lib_id.cc:358
void id_us_min(ID *id)
Definition lib_id.cc:366
IDOverrideLibraryProperty * BKE_lib_override_library_property_get(IDOverrideLibrary *liboverride, const char *rna_path, bool *r_created)
IDOverrideLibraryPropertyOperation * BKE_lib_override_library_property_operation_get(IDOverrideLibraryProperty *liboverride_property, short operation, const char *subitem_refname, const char *subitem_locname, const std::optional< ID * > &subitem_refid, const std::optional< ID * > &subitem_locid, int subitem_refindex, int subitem_locindex, bool strict, bool *r_strict, bool *r_created)
void BKE_nla_tweakmode_exit(OwnedAnimData owned_adt)
NlaTrack * BKE_nlatrack_copy(Main *bmain, NlaTrack *nlt, bool use_same_actions, int flag)
void BKE_nlatrack_set_active(ListBase *tracks, NlaTrack *nlt)
NlaTrack * BKE_nlatrack_new_after(ListBase *nla_tracks, NlaTrack *prev, bool is_liboverride)
NlaTrack * BKE_nlatrack_new_tail(ListBase *nla_tracks, const bool is_liboverride)
bool BKE_nla_tweakmode_enter(OwnedAnimData owned_adt)
NlaTrack * BKE_nlatrack_find_active(ListBase *tracks)
void BKE_nlatrack_remove_and_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_INFO
Definition BKE_report.hh:35
@ RPT_ERROR
Definition BKE_report.hh:39
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
void BLI_kdtree_nd_ free(KDTree *tree)
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition listbase.cc:332
bool BLI_remlink_safe(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:154
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
MINLINE int max_ii(int a, int b)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
#define STRNCPY_UTF8(dst, src)
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_ACTION
#define BLT_I18NCONTEXT_ID_ID
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1077
@ LIBOVERRIDE_OP_REPLACE
Definition DNA_ID.h:230
@ LIBOVERRIDE_OP_INSERT_AFTER
Definition DNA_ID.h:240
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:730
@ ID_OB
@ ADT_CURVES_ALWAYS_VISIBLE
@ ADT_NLA_EVAL_OFF
@ ADT_NLA_EDIT_ON
@ KEYINGSET_ABSOLUTE
@ INSERTKEY_CYCLE_AWARE
@ INSERTKEY_REPLACE
@ INSERTKEY_MATRIX
@ INSERTKEY_NEEDED
@ INSERTKEY_AVAILABLE
@ KSP_GROUP_KSNAME
@ KSP_GROUP_NAMED
@ KSP_GROUP_NONE
@ KSP_FLAG_WHOLE_ARRAY
Object is a sort of wrapper for general info.
@ DRIVER_FCURVE_KEYFRAMES
@ RNA_OVERRIDE_COMPARE_CREATE
StructRNA * ID_code_to_RNA_type(short idcode)
@ RNA_OVERRIDE_MATCH_RESULT_CREATED
#define RNA_DYN_DESCR_MAX
ParameterFlag
Definition RNA_types.hh:544
@ PARM_RNAPTR
Definition RNA_types.hh:547
@ PARM_REQUIRED
Definition RNA_types.hh:545
@ FUNC_USE_REPORTS
Definition RNA_types.hh:914
@ FUNC_REGISTER
Definition RNA_types.hh:921
@ FUNC_USE_MAIN
Definition RNA_types.hh:912
@ FUNC_USE_CONTEXT
Definition RNA_types.hh:913
@ FUNC_USE_SELF_ID
Definition RNA_types.hh:889
int(*)(PointerRNA *ptr, void *data, bool *have_function) StructValidateFunc
Definition RNA_types.hh:985
@ PROP_FLOAT
Definition RNA_types.hh:164
@ PROP_BOOLEAN
Definition RNA_types.hh:162
@ PROP_ENUM
Definition RNA_types.hh:166
@ PROP_INT
Definition RNA_types.hh:163
@ PROP_STRING
Definition RNA_types.hh:165
@ PROP_POINTER
Definition RNA_types.hh:167
@ PROP_COLLECTION
Definition RNA_types.hh:168
int(*)(bContext *C, PointerRNA *ptr, FunctionRNA *func, ParameterList *list) StructCallbackFunc
Definition RNA_types.hh:986
void(*)(void *data) StructFreeFunc
Definition RNA_types.hh:990
@ PROPOVERRIDE_OVERRIDABLE_LIBRARY
Definition RNA_types.hh:503
@ PROPOVERRIDE_IGNORE
Definition RNA_types.hh:523
@ PROPOVERRIDE_LIBRARY_INSERTION
Definition RNA_types.hh:528
@ PROPOVERRIDE_NO_PROP_NAME
Definition RNA_types.hh:536
PropertyFlag
Definition RNA_types.hh:300
@ PROP_THICK_WRAP
Definition RNA_types.hh:423
@ PROP_ANIMATABLE
Definition RNA_types.hh:319
@ PROP_EDITABLE
Definition RNA_types.hh:306
@ PROP_ENUM_FLAG
Definition RNA_types.hh:404
@ PROP_REGISTER_OPTIONAL
Definition RNA_types.hh:412
@ PROP_NEVER_NULL
Definition RNA_types.hh:377
@ PROP_NO_DEG_UPDATE
Definition RNA_types.hh:439
@ PROP_REGISTER
Definition RNA_types.hh:411
@ PROP_HIDDEN
Definition RNA_types.hh:338
@ PROP_ID_REFCOUNT
Definition RNA_types.hh:364
@ PROP_NONE
Definition RNA_types.hh:233
@ PROP_FACTOR
Definition RNA_types.hh:251
#define C
Definition RandGen.cpp:29
#define NC_WINDOW
Definition WM_types.hh:375
#define ND_NLA_ACTCHANGE
Definition WM_types.hh:498
#define NC_ANIMATION
Definition WM_types.hh:388
#define ND_KEYINGSET
Definition WM_types.hh:448
#define NC_SCENE
Definition WM_types.hh:378
#define NA_ADDED
Definition WM_types.hh:586
#define NA_EDITED
Definition WM_types.hh:584
#define NA_REMOVED
Definition WM_types.hh:587
#define ND_NLA
Definition WM_types.hh:497
#define NA_RENAME
Definition WM_types.hh:588
#define ND_ANIMCHAN
Definition WM_types.hh:496
#define NA_SELECTED
Definition WM_types.hh:589
void ANIM_id_update(Main *bmain, ID *id)
Definition anim_deps.cc:103
BMesh const char void * data
constexpr const T * data() const
Definition BLI_span.hh:215
constexpr int64_t size() const
Definition BLI_span.hh:252
blender::Span< const Slot * > slots() const
Slot * slot_for_handle(slot_handle_t handle)
static void users_invalidate(Main &bmain)
bool is_suitable_for(const ID &animated_id) const
static constexpr slot_handle_t unassigned
FCurve * verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, eDriverFCurveCreationMode creation_mode)
Definition drivers.cc:51
#define GS(x)
DEG_id_tag_update_ex(cb_data->bmain, cb_data->owner_id, ID_RECALC_TAG_FOR_UNDO|ID_RECALC_SYNC_TO_EVAL)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
Vector< bActionGroup * > channel_groups_for_assigned_slot(AnimData *adt)
KeyingSetInfo * keyingset_info_find_name(const char name[])
ActionSlotAssignmentResult generic_assign_action_slot(Slot *slot_to_assign, ID &animated_id, bAction *&action_ptr_ref, slot_handle_t &slot_handle_ref, char *slot_identifier)
decltype(::ActionSlot::handle) slot_handle_t
void keyingset_info_register(KeyingSetInfo *keyingset_info)
Action * get_action(ID &animated_id)
void keyingset_info_unregister(Main *bmain, KeyingSetInfo *keyingset_info)
bool assign_tmpaction(bAction *action, OwnedAnimData owned_adt)
bool assign_action(bAction *action, ID &animated_id)
ActionSlotAssignmentResult generic_assign_action_slot_handle(slot_handle_t slot_handle_to_assign, ID &animated_id, bAction *&action_ptr_ref, slot_handle_t &slot_handle_ref, char *slot_identifier)
return ret
const EnumPropertyItem rna_enum_id_type_items[]
Definition rna_ID.cc:29
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type)
const PointerRNA PointerRNA_NULL
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
void * RNA_struct_blender_type_get(StructRNA *srna)
void RNA_parameter_list_free(ParameterList *parms)
void RNA_property_update_main(Main *bmain, Scene *scene, PointerRNA *ptr, PropertyRNA *prop)
void RNA_parameter_set_lookup(ParameterList *parms, const char *identifier, const void *value)
void rna_iterator_array_begin(CollectionPropertyIterator *iter, PointerRNA *ptr, void *data, size_t itemsize, int64_t length, bool free_ptr, IteratorSkipFunc skip)
ParameterList * RNA_parameter_list_create(ParameterList *parms, PointerRNA *, FunctionRNA *func)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
void RNA_parameter_get_lookup(ParameterList *parms, const char *identifier, void **r_value)
PointerRNA RNA_pointer_create_with_parent(const PointerRNA &parent, StructRNA *type, void *data)
PointerRNA RNA_id_pointer_create(ID *id)
static void rna_def_common_keying_flags(StructRNA *srna, short reg)
const EnumPropertyItem rna_enum_keying_flag_api_items[]
void RNA_def_animation(BlenderRNA *brna)
static void rna_api_animdata_nla_tracks(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_animdata(BlenderRNA *brna)
static void rna_def_keyingset_paths(BlenderRNA *brna, PropertyRNA *cprop)
const EnumPropertyItem rna_enum_keying_flag_items[]
#define KEYINGSET_IDNAME_DOC
const EnumPropertyItem rna_enum_keyingset_path_grouping_items[]
static void rna_api_animdata_drivers(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_keyingset_path(BlenderRNA *brna)
static void rna_def_keyingset(BlenderRNA *brna)
void rna_def_animdata_common(StructRNA *srna)
static void rna_def_keyingset_info(BlenderRNA *brna)
void RNA_api_keyingset(StructRNA *srna)
void RNA_api_animdata(StructRNA *srna)
void RNA_def_property_boolean_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t booleanbit)
void RNA_def_struct_name_property(StructRNA *srna, PropertyRNA *prop)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_struct_refine_func(StructRNA *srna, const char *refine)
void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_define_lib_overridable(const bool make_overridable)
void RNA_def_struct_path_func(StructRNA *srna, const char *path)
void RNA_def_parameter_clear_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const char *length, const char *set)
void RNA_def_property_float_default(PropertyRNA *prop, float value)
void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
void RNA_def_property_enum_default(PropertyRNA *prop, int value)
void RNA_define_verify_sdna(bool verify)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
void RNA_def_property_string_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_srna(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring, const char *assignint)
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description)
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set)
void RNA_def_struct_register_funcs(StructRNA *srna, const char *reg, const char *unreg, const char *instance)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_enum_items(PropertyRNA *prop, const EnumPropertyItem *item)
void RNA_def_struct_sdna(StructRNA *srna, const char *structname)
FunctionRNA * RNA_def_function(StructRNA *srna, const char *identifier, const char *call)
void RNA_def_property_range(PropertyRNA *prop, double min, double max)
PropertyRNA * RNA_def_pointer(StructOrFunctionRNA *cont_, const char *identifier, const char *type, const char *ui_name, const char *ui_description)
void RNA_def_property_string_maxlength(PropertyRNA *prop, int maxlength)
void RNA_def_property_struct_type(PropertyRNA *prop, const char *type)
void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname)
void RNA_def_function_ui_description(FunctionRNA *func, const char *description)
void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
void RNA_def_property_enum_funcs(PropertyRNA *prop, const char *get, const char *set, const char *item)
StructRNA * RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRNA *srnafrom)
void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable)
StructRNA * RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *from)
void RNA_def_function_flag(FunctionRNA *func, int flag)
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *rna_ext)
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *type_fn, const char *poll)
void RNA_def_property_enum_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range)
void RNA_def_struct_ui_icon(StructRNA *srna, int icon)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
void RNA_def_property_override_funcs(PropertyRNA *prop, const char *diff, const char *store, const char *apply)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const char *propname)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
void RNA_def_property_boolean_negative_sdna(PropertyRNA *prop, const char *structname, const char *propname, int64_t booleanbit)
void RNA_def_property_override_flag(PropertyRNA *prop, PropertyOverrideFlag flag)
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter)
void rna_property_override_diff_default(Main *bmain, RNAPropertyOverrideDiffContext &rnadiff_ctx)
BlenderRNA BLENDER_RNA
bool rna_AnimaData_override_apply(Main *bmain, RNAPropertyOverrideApplyContext &rnaapply_ctx)
const EnumPropertyItem rna_enum_nla_mode_blend_items[]
Definition rna_nla.cc:30
const EnumPropertyItem rna_enum_nla_mode_extend_items[]
Definition rna_nla.cc:61
#define min(a, b)
Definition sort.cc:36
char identifier[258]
char tmp_last_slot_identifier[258]
bAction * action
short act_blendmode
NlaStrip * actstrip
float act_influence
int32_t slot_handle
NlaTrack * act_track
int32_t tmp_slot_handle
bAction * tmpact
short act_extendmode
ListBase drivers
ListBase nla_tracks
char last_slot_identifier[258]
StructRNA * srna
StructCallbackFunc call
StructFreeFunc free
ChannelDriver * driver
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
struct KS_Path * next
short groupmode
cbKeyingSet_Generate generate
ExtensionRNA rna_ext
cbKeyingSet_Iterator iter
cbKeyingSet_Poll poll
char name[64]
char typeinfo[64]
ListBase paths
void * first
char name[64]
ID * owner_id
Definition RNA_types.hh:51
void invalidate()
Definition RNA_types.hh:110
void * data
Definition RNA_types.hh:53
IDOverrideLibraryPropertyOperation * liboverride_operation
eRNAOverrideMatchResult report_flag
max
Definition text_draw.cc:251
void WM_global_report(eReportType type, const char *message)
void WM_main_add_notifier(uint type, void *reference)
void WM_global_reportf(eReportType type, const char *format,...)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4238
uint8_t flag
Definition wm_window.cc:145