Blender V4.3
nla_tracks.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors, Joshua Leung. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cmath>
10#include <cstdio>
11#include <cstdlib>
12#include <cstring>
13
14#include "DNA_anim_types.h"
15#include "DNA_object_types.h"
16#include "DNA_scene_types.h"
17
18#include "BLI_utildefines.h"
19
20#include "BKE_anim_data.hh"
21#include "BKE_context.hh"
22#include "BKE_global.hh"
23#include "BKE_layer.hh"
24#include "BKE_nla.hh"
25#include "BKE_report.hh"
26
27#include "ANIM_action.hh"
28
29#include "ED_anim_api.hh"
30#include "ED_keyframes_edit.hh"
31#include "ED_object.hh"
32#include "ED_screen.hh"
33
34#include "RNA_access.hh"
35#include "RNA_define.hh"
36
37#include "WM_api.hh"
38#include "WM_types.hh"
39
40#include "DEG_depsgraph.hh"
42
43#include "UI_view2d.hh"
44
45#include "nla_intern.hh" /* own include */
46
47/* *********************************************** */
48/* Operators for NLA track-list which need to be different
49 * from the standard Animation Editor ones */
50
51/* ******************** Mouse-Click Operator *********************** */
52/* Depending on the track that was clicked on, the mouse click will activate whichever
53 * part of the track is relevant.
54 *
55 * NOTE: eventually,
56 * this should probably be phased out when many of these things are replaced with buttons
57 * --> Most tracks are now selection only.
58 */
59
60static int mouse_nla_tracks(bContext *C, bAnimContext *ac, int track_index, short selectmode)
61{
62 ListBase anim_data = {nullptr, nullptr};
63
64 int notifierFlags = 0;
65
66 /* get the track that was clicked on */
67 /* filter tracks */
70 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
71
72 /* get track from index */
73 bAnimListElem *ale = static_cast<bAnimListElem *>(BLI_findlink(&anim_data, track_index));
74 if (ale == nullptr) {
75 /* track not found */
76 if (G.debug & G_DEBUG) {
77 printf("Error: animation track (index = %d) not found in mouse_nla_tracks()\n", track_index);
78 }
79
80 ANIM_animdata_freelist(&anim_data);
81 return 0;
82 }
83
84 /* action to take depends on what track we've got */
85 /* WARNING: must keep this in sync with the equivalent function in `anim_channels_edit.cc`. */
86 switch (ale->type) {
87 case ANIMTYPE_SCENE: {
88 Scene *sce = static_cast<Scene *>(ale->data);
89 AnimData *adt = sce->adt;
90
91 /* set selection status */
92 if (selectmode == SELECT_INVERT) {
93 /* swap select */
94 sce->flag ^= SCE_DS_SELECTED;
95 if (adt) {
96 adt->flag ^= ADT_UI_SELECTED;
97 }
98 }
99 else {
100 sce->flag |= SCE_DS_SELECTED;
101 if (adt) {
102 adt->flag |= ADT_UI_SELECTED;
103 }
104 }
105
106 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
107 break;
108 }
109 case ANIMTYPE_OBJECT: {
110 ViewLayer *view_layer = ac->view_layer;
111 Base *base = static_cast<Base *>(ale->data);
112 Object *ob = base->object;
113 AnimData *adt = ob->adt;
114
115 if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLE)) {
116 /* set selection status */
117 if (selectmode == SELECT_INVERT) {
118 /* swap select */
120
121 if (adt) {
122 adt->flag ^= ADT_UI_SELECTED;
123 }
124 }
125 else {
126 /* deselect all */
127 /* TODO: should this deselect all other types of tracks too? */
128 BKE_view_layer_synced_ensure(ac->scene, view_layer);
131 if (b->object->adt) {
132 b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
133 }
134 }
135
136 /* select object now */
138 if (adt) {
139 adt->flag |= ADT_UI_SELECTED;
140 }
141 }
142
143 /* change active object - regardless of whether it is now selected [#37883] */
145
146 if ((adt) && (adt->flag & ADT_UI_SELECTED)) {
147 adt->flag |= ADT_UI_ACTIVE;
148 }
149
150 /* notifiers - track was selected */
151 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
152 }
153 break;
154 }
155 case ANIMTYPE_FILLACTD: /* Action Expander */
156 case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
157 case ANIMTYPE_DSLAM:
158 case ANIMTYPE_DSCAM:
160 case ANIMTYPE_DSCUR:
161 case ANIMTYPE_DSSKEY:
162 case ANIMTYPE_DSWOR:
163 case ANIMTYPE_DSNTREE:
164 case ANIMTYPE_DSPART:
165 case ANIMTYPE_DSMBALL:
166 case ANIMTYPE_DSARM:
167 case ANIMTYPE_DSMESH:
168 case ANIMTYPE_DSTEX:
169 case ANIMTYPE_DSLAT:
171 case ANIMTYPE_DSSPK:
173 case ANIMTYPE_PALETTE:
174 case ANIMTYPE_DSHAIR:
176 case ANIMTYPE_DSVOLUME: {
177 /* sanity checking... */
178 if (ale->adt) {
179 /* select/deselect */
180 if (selectmode == SELECT_INVERT) {
181 /* inverse selection status of this AnimData block only */
182 ale->adt->flag ^= ADT_UI_SELECTED;
183 }
184 else {
185 /* select AnimData block by itself */
187 ale->adt->flag |= ADT_UI_SELECTED;
188 }
189
190 /* set active? */
191 if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) {
192 ale->adt->flag |= ADT_UI_ACTIVE;
193 }
194 }
195
196 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
197 break;
198 }
199 case ANIMTYPE_NLATRACK: {
200 NlaTrack *nlt = static_cast<NlaTrack *>(ale->data);
201
202 if (nlaedit_is_tweakmode_on(ac) == 0) {
203 /* set selection */
204 if (selectmode == SELECT_INVERT) {
205 /* inverse selection status of this F-Curve only */
206 nlt->flag ^= NLATRACK_SELECTED;
207 }
208 else {
209 /* select F-Curve by itself */
211 nlt->flag |= NLATRACK_SELECTED;
212 }
213
214 /* if NLA-Track is selected now,
215 * make NLA-Track the 'active' one in the visible list */
216 if (nlt->flag & NLATRACK_SELECTED) {
218 ac, ac->data, eAnimCont_Types(ac->datatype), filter, nlt, ANIMTYPE_NLATRACK);
219 }
220
221 /* notifier flags - track was selected */
222 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
223 }
224 break;
225 }
226 case ANIMTYPE_NLAACTION: {
227 AnimData *adt = BKE_animdata_from_id(ale->id);
228
229 /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
230 * - this is useful when there's no clear divider, and makes more sense in
231 * the case of users trying to use this to change actions
232 * - in tweak-mode, clicking here gets us out of tweak-mode, as changing selection
233 * while in tweak-mode is really evil!
234 * - we disable "solo" flags too, to make it easier to work with stashed actions
235 * with less trouble
236 */
237 if (nlaedit_is_tweakmode_on(ac)) {
238 /* Exit tweak-mode immediately. */
240
241 /* changes to NLA-Action occurred */
242 notifierFlags |= ND_NLA_ACTCHANGE;
243 ale->update |= ANIM_UPDATE_DEPS;
244 }
245 else {
246 /* select/deselect */
247 if (selectmode == SELECT_INVERT) {
248 /* inverse selection status of this AnimData block only */
249 adt->flag ^= ADT_UI_SELECTED;
250 }
251 else {
252 /* select AnimData block by itself */
254 adt->flag |= ADT_UI_SELECTED;
255 }
256
257 /* set active? */
258 if (adt->flag & ADT_UI_SELECTED) {
259 adt->flag |= ADT_UI_ACTIVE;
260 }
261
262 notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
263 }
264 break;
265 }
268 /* The NLA doesn't support layered Actions. */
269 break;
270 default:
271 if (G.debug & G_DEBUG) {
272 printf("Error: Invalid track type in mouse_nla_tracks()\n");
273 }
274 break;
275 }
276
277 /* free tracks */
278 ANIM_animdata_update(ac, &anim_data);
279 ANIM_animdata_freelist(&anim_data);
280
281 /* return the notifier-flags set */
282 return notifierFlags;
283}
284
285/* ------------------- */
286
287/* handle clicking */
289{
290 bAnimContext ac;
291 ARegion *region;
292 View2D *v2d;
293 int track_index;
294 int notifierFlags = 0;
295 short selectmode;
296 float x, y;
297
298 /* get editor data */
299 if (ANIM_animdata_get_context(C, &ac) == 0) {
300 return OPERATOR_CANCELLED;
301 }
302
303 /* get useful pointers from animation context data */
304 SpaceNla *snla = reinterpret_cast<SpaceNla *>(ac.sl);
305 region = ac.region;
306 v2d = &region->v2d;
307
308 /* select mode is either replace (deselect all, then add) or add/extend */
309 if (RNA_boolean_get(op->ptr, "extend")) {
310 selectmode = SELECT_INVERT;
311 }
312 else {
313 selectmode = SELECT_REPLACE;
314 }
315
316 /* Figure out which track user clicked in. */
317 UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
319 NLATRACK_STEP(snla),
320 0,
322 x,
323 y,
324 nullptr,
325 &track_index);
326
327 /* handle mouse-click in the relevant track then */
328 notifierFlags = mouse_nla_tracks(C, &ac, track_index, selectmode);
329
330 /* set notifier that things have changed */
331 WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, nullptr);
332
333 return OPERATOR_FINISHED;
334}
335
337{
338 PropertyRNA *prop;
339
340 /* identifiers */
341 ot->name = "Mouse Click on NLA Tracks";
342 ot->idname = "NLA_OT_channels_click";
343 ot->description = "Handle clicks to select NLA tracks";
344
345 /* api callbacks */
348
349 /* flags */
351
352 /* props */
353 prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); /* SHIFTKEY */
355}
356
357/* *********************************************** */
358/* Special Operators */
359
360/* ******************** Action Push Down ******************************** */
361
363{
364 bAnimContext ac;
365 ID *id = nullptr;
366 AnimData *adt = nullptr;
367 int track_index = RNA_int_get(op->ptr, "track_index");
368
369 /* get editor data */
370 if (ANIM_animdata_get_context(C, &ac) == 0) {
371 return OPERATOR_CANCELLED;
372 }
373
374 /* get anim-channel to use (or more specifically, the animdata block behind it) */
375 if (track_index == -1) {
376 PointerRNA adt_ptr = {nullptr};
377
378 /* active animdata block */
379 if (nla_panel_context(C, &adt_ptr, nullptr, nullptr) == 0 || (adt_ptr.data == nullptr)) {
381 RPT_ERROR,
382 "No active AnimData block to use "
383 "(select a data-block expander first or set the appropriate flags on an AnimData "
384 "block)");
385 return OPERATOR_CANCELLED;
386 }
387
388 id = adt_ptr.owner_id;
389 adt = static_cast<AnimData *>(adt_ptr.data);
390 }
391 else {
392 /* indexed track */
393 ListBase anim_data = {nullptr, nullptr};
394
395 /* filter tracks */
398 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
399
400 /* get track from index */
401 bAnimListElem *ale = static_cast<bAnimListElem *>(BLI_findlink(&anim_data, track_index));
402 if (ale == nullptr) {
403 BKE_reportf(op->reports, RPT_ERROR, "No animation track found at index %d", track_index);
404 ANIM_animdata_freelist(&anim_data);
405 return OPERATOR_CANCELLED;
406 }
407 if (ale->type != ANIMTYPE_NLAACTION) {
409 RPT_ERROR,
410 "Animation track at index %d is not a NLA 'Active Action' track",
411 track_index);
412 ANIM_animdata_freelist(&anim_data);
413 return OPERATOR_CANCELLED;
414 }
415
416 /* grab AnimData from the track */
417 adt = ale->adt;
418 id = ale->id;
419
420 /* we don't need anything here anymore, so free it all */
421 ANIM_animdata_freelist(&anim_data);
422 }
423
424 /* double-check that we are free to push down here... */
425 if (adt == nullptr) {
426 BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
427 return OPERATOR_CANCELLED;
428 }
429 if (nlaedit_is_tweakmode_on(&ac)) {
432 "Cannot push down actions while tweaking a strip's action, exit tweak mode first");
433 return OPERATOR_CANCELLED;
434 }
435
436 bAction *action_to_push_down = adt->action;
437 if (!action_to_push_down) {
438 BKE_report(op->reports, RPT_WARNING, "No active action to push down");
439 return OPERATOR_CANCELLED;
440 }
441
442 /* 'push-down' action - only usable when not in Tweak-mode. */
444
445 Main *bmain = CTX_data_main(C);
447
448 /* The action needs updating too, as FCurve modifiers are to be reevaluated. They won't extend
449 * beyond the NLA strip after pushing down to the NLA. */
450 DEG_id_tag_update_ex(bmain, &action_to_push_down->id, ID_RECALC_ANIMATION);
451
452 /* set notifier that things have changed */
454 return OPERATOR_FINISHED;
455}
456
458{
459 /* identifiers */
460 ot->name = "Push Down Action";
461 ot->idname = "NLA_OT_action_pushdown";
462 ot->description = "Push action down onto the top of the NLA stack as a new strip";
463
464 /* callbacks */
467
468 /* flags */
470
471 /* properties */
473 "track_index",
474 -1,
475 -1,
476 INT_MAX,
477 "Track Index",
478 "Index of NLA action track to perform pushdown operation on",
479 0,
480 INT_MAX);
482}
483
484/* ******************** Action Unlink ******************************** */
485
487{
488 if (ED_operator_nla_active(C)) {
489 PointerRNA adt_ptr;
490 return (nla_panel_context(C, &adt_ptr, nullptr, nullptr) && (adt_ptr.data != nullptr));
491 }
492
493 /* something failed... */
494 return false;
495}
496
498{
499 PointerRNA adt_ptr;
500
501 /* check context and also validity of pointer */
502 if (!nla_panel_context(C, &adt_ptr, nullptr, nullptr)) {
503 return OPERATOR_CANCELLED;
504 }
505
506 /* get animdata */
507 AnimData *adt = static_cast<AnimData *>(adt_ptr.data);
508 if (adt == nullptr) {
509 return OPERATOR_CANCELLED;
510 }
511
512 /* do unlinking */
513 if (adt->action) {
514 bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
515 ED_animedit_unlink_action(C, adt_ptr.owner_id, adt, adt->action, op->reports, force_delete);
516 }
517
518 return OPERATOR_FINISHED;
519}
520
521static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *event)
522{
523 /* NOTE: this is hardcoded to match the behavior for the unlink button
524 * (in `interface_templates.cc`). */
525 RNA_boolean_set(op->ptr, "force_delete", event->modifier & KM_SHIFT);
526 return nla_action_unlink_exec(C, op);
527}
528
530{
531 PropertyRNA *prop;
532
533 /* identifiers */
534 ot->name = "Unlink Action";
535 ot->idname = "NLA_OT_action_unlink";
536 ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
537
538 /* callbacks */
542
543 /* properties */
544 prop = RNA_def_boolean(ot->srna,
545 "force_delete",
546 false,
547 "Force Delete",
548 "Clear Fake User and remove copy stashed in this data-block's NLA stack");
550}
551
552/* ******************** Add Tracks Operator ***************************** */
553/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
554
556{
557 ListBase anim_data = {nullptr, nullptr};
558 AnimData *lastAdt = nullptr;
559 bool added = false;
560
561 /* get a list of the (selected) NLA Tracks being shown in the NLA */
564 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
565
566 /* add tracks... */
567 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
568 if (ale->type == ANIMTYPE_NLATRACK) {
569 NlaTrack *nlt = static_cast<NlaTrack *>(ale->data);
570 AnimData *adt = ale->adt;
571 NlaTrack *new_track = nullptr;
572
573 const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
574
575 /* check if just adding a new track above this one,
576 * or whether we're adding a new one to the top of the stack that this one belongs to
577 */
578 if (above_sel) {
579 /* just add a new one above this one */
580 new_track = BKE_nlatrack_new_after(&adt->nla_tracks, nlt, is_liboverride);
581 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
582 ale->update = ANIM_UPDATE_DEPS;
583 added = true;
584 }
585 else if ((lastAdt == nullptr) || (adt != lastAdt)) {
586 /* add one track to the top of the owning AnimData's stack,
587 * then don't add anymore to this stack */
588 new_track = BKE_nlatrack_new_tail(&adt->nla_tracks, is_liboverride);
589 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
590 lastAdt = adt;
591 ale->update = ANIM_UPDATE_DEPS;
592 added = true;
593 }
594 }
595 }
596
597 /* free temp data */
598 ANIM_animdata_update(ac, &anim_data);
599 ANIM_animdata_freelist(&anim_data);
600
601 return added;
602}
603
605{
606 ListBase anim_data = {nullptr, nullptr};
607
608 bool added = false;
609
610 /* get a list of the selected AnimData blocks in the NLA */
614 ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
615
616 /* check if selected AnimData blocks are empty, and add tracks if so... */
617 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
618 AnimData *adt = ale->adt;
619 NlaTrack *new_track;
620
621 /* sanity check */
623
624 /* ensure it is empty */
626 /* add new track to this AnimData block then */
627 new_track = BKE_nlatrack_new_tail(&adt->nla_tracks, ID_IS_OVERRIDE_LIBRARY(ale->id));
628 BKE_nlatrack_set_active(&adt->nla_tracks, new_track);
629 ale->update = ANIM_UPDATE_DEPS;
630 added = true;
631 }
632 }
633
634 /* cleanup */
635 ANIM_animdata_update(ac, &anim_data);
636 ANIM_animdata_freelist(&anim_data);
637
638 return added;
639}
640
641/* ----- */
642
644{
645 bAnimContext ac;
646 bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
647 bool op_done = false;
648
649 /* get editor data */
650 if (ANIM_animdata_get_context(C, &ac) == 0) {
651 return OPERATOR_CANCELLED;
652 }
653
654 /* perform adding in two passes - existing first so that we don't double up for empty */
655 op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
656 op_done |= nlaedit_add_tracks_empty(&ac);
657
658 /* done? */
659 if (op_done) {
661
662 /* set notifier that things have changed */
664
665 /* done */
666 return OPERATOR_FINISHED;
667 }
668
669 /* failed to add any tracks */
671 op->reports, RPT_WARNING, "Select an existing NLA Track or an empty action line first");
672
673 /* not done */
674 return OPERATOR_CANCELLED;
675}
676
678{
679 /* identifiers */
680 ot->name = "Add Tracks";
681 ot->idname = "NLA_OT_tracks_add";
682 ot->description = "Add NLA-Tracks above/after the selected tracks";
683
684 /* api callbacks */
687
688 /* flags */
690
691 /* properties */
693 "above_selected",
694 false,
695 "Above Selected",
696 "Add a new NLA Track above every existing selected one");
697}
698
699/* ******************** Delete Tracks Operator ***************************** */
700/* Delete selected NLA Tracks */
701
703{
704 bAnimContext ac;
705
706 ListBase anim_data = {nullptr, nullptr};
707
708 /* get editor data */
709 if (ANIM_animdata_get_context(C, &ac) == 0) {
710 return OPERATOR_CANCELLED;
711 }
712
713 /* get a list of the AnimData blocks being shown in the NLA */
716 ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype));
717
718 /* delete tracks */
719 LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
720 if (ale->type == ANIMTYPE_NLATRACK) {
721 NlaTrack *nlt = static_cast<NlaTrack *>(ale->data);
722 AnimData *adt = ale->adt;
723
724 if (BKE_nlatrack_is_nonlocal_in_liboverride(ale->id, nlt)) {
725 /* No deletion of non-local tracks of override data. */
726 continue;
727 }
728
729 /* if track is currently 'solo', then AnimData should have its
730 * 'has solo' flag disabled
731 */
732 if (nlt->flag & NLATRACK_SOLO) {
733 adt->flag &= ~ADT_NLA_SOLO_TRACK;
734 }
735
736 /* call delete on this track - deletes all strips too */
738 ale->update = ANIM_UPDATE_DEPS;
739 }
740 }
741
742 /* free temp data */
743 ANIM_animdata_update(&ac, &anim_data);
744 ANIM_animdata_freelist(&anim_data);
745
747
748 /* set notifier that things have changed */
750
751 /* done */
752 return OPERATOR_FINISHED;
753}
754
756{
757 /* identifiers */
758 ot->name = "Delete Tracks";
759 ot->idname = "NLA_OT_tracks_delete";
760 ot->description = "Delete selected NLA-Tracks and the strips they contain";
761
762 /* api callbacks */
765
766 /* flags */
768}
769
770/* *********************************************** */
771/* AnimData Related Operators */
772
773/* ******************** Include Objects Operator ***************************** */
774/* Include selected objects in NLA Editor, by giving them AnimData blocks
775 * NOTE: This doesn't help for non-object AnimData, where we do not have any effective
776 * selection mechanism in place. Unfortunately, this means that non-object AnimData
777 * once again becomes a second-class citizen here. However, at least for the most
778 * common use case, we now have a nice shortcut again.
779 */
780
782{
783 bAnimContext ac;
784
785 /* get editor data */
786 if (ANIM_animdata_get_context(C, &ac) == 0) {
787 return OPERATOR_CANCELLED;
788 }
789
790 /* ensure that filters are set so that the effect will be immediately visible */
791 SpaceNla *snla = reinterpret_cast<SpaceNla *>(ac.sl);
792 if (snla && snla->ads) {
793 snla->ads->filterflag &= ~ADS_FILTER_NLA_NOACT;
794 }
795
796 /* operate on selected objects... */
797 CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
798 /* ensure that object has AnimData... that's all */
799 BKE_animdata_ensure_id(&ob->id);
800 }
802
803 /* set notifier that things have changed */
805
806 /* done */
807 return OPERATOR_FINISHED;
808}
809
811{
812 /* identifiers */
813 ot->name = "Include Selected Objects";
814 ot->idname = "NLA_OT_selected_objects_add";
815 ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
816
817 /* api callbacks */
820
821 /* flags */
823}
824
825/* *********************************************** */
Functions and classes to work with Actions.
AnimData * BKE_animdata_ensure_id(ID *id)
Definition anim_data.cc:103
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
#define CTX_DATA_BEGIN(C, Type, instance, member)
Main * CTX_data_main(const bContext *C)
#define CTX_DATA_END
@ G_DEBUG
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ListBase * BKE_view_layer_object_bases_get(ViewLayer *view_layer)
void BKE_nla_action_pushdown(OwnedAnimData owned_adt, bool is_liboverride)
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_nlatrack_is_nonlocal_in_liboverride(const ID *id, const NlaTrack *nlt)
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
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void DEG_id_tag_update_ex(Main *bmain, ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1044
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition DNA_ID.h:683
@ ADT_UI_ACTIVE
@ ADT_UI_SELECTED
@ NLATRACK_SOLO
@ NLATRACK_SELECTED
Object is a sort of wrapper for general info.
@ SCE_DS_SELECTED
#define BASE_SELECTABLE(v3d, base)
@ ACHANNEL_SETFLAG_CLEAR
@ ANIMTYPE_DSSPK
@ ANIMTYPE_DSTEX
@ ANIMTYPE_DSNTREE
@ ANIMTYPE_DSMBALL
@ ANIMTYPE_DSCAM
@ ANIMTYPE_DSPOINTCLOUD
@ ANIMTYPE_DSPART
@ ANIMTYPE_DSLINESTYLE
@ ANIMTYPE_ACTION_SLOT
@ ANIMTYPE_DSCUR
@ ANIMTYPE_SCENE
@ ANIMTYPE_DSARM
@ ANIMTYPE_DSGPENCIL
@ ANIMTYPE_DSLAT
@ ANIMTYPE_NLAACTION
@ ANIMTYPE_DSMAT
@ ANIMTYPE_DSCACHEFILE
@ ANIMTYPE_DSVOLUME
@ ANIMTYPE_DSLAM
@ ANIMTYPE_PALETTE
@ ANIMTYPE_FILLACT_LAYERED
@ ANIMTYPE_FILLACTD
@ ANIMTYPE_OBJECT
@ ANIMTYPE_DSMESH
@ ANIMTYPE_NLATRACK
@ ANIMTYPE_DSWOR
@ ANIMTYPE_DSSKEY
@ ANIMTYPE_DSHAIR
#define NLATRACK_FIRST_TOP(ac)
#define NLATRACK_STEP(snla)
@ ANIM_UPDATE_DEPS
eAnimCont_Types
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports, bool force_delete)
#define NLATRACK_NAMEWIDTH
eAnimFilter_Flags
@ ANIMFILTER_ANIMDATA
@ ANIMFILTER_DATA_VISIBLE
@ ANIMFILTER_LIST_VISIBLE
@ ANIMFILTER_LIST_CHANNELS
@ ANIMFILTER_NODUPLIS
@ ANIMFILTER_FCURVESONLY
@ ANIMFILTER_SEL
@ SELECT_INVERT
@ SELECT_REPLACE
bool ED_operator_nla_active(bContext *C)
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
@ PROP_HIDDEN
Definition RNA_types.hh:239
void UI_view2d_listview_view_to_cell(float columnwidth, float rowheight, float startx, float starty, float viewx, float viewy, int *r_column, int *r_row)
Definition view2d.cc:1616
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
Definition view2d.cc:1663
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define ND_NLA_ACTCHANGE
Definition WM_types.hh:465
#define NC_ANIMATION
Definition WM_types.hh:355
#define NA_ADDED
Definition WM_types.hh:552
#define NA_EDITED
Definition WM_types.hh:550
#define NA_REMOVED
Definition WM_types.hh:553
#define ND_NLA
Definition WM_types.hh:464
@ KM_SHIFT
Definition WM_types.hh:255
#define ND_ANIMCHAN
Definition WM_types.hh:463
#define NA_SELECTED
Definition WM_types.hh:555
void ANIM_anim_channels_select_set(bAnimContext *ac, eAnimChannels_SetFlag sel)
void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datatype, eAnimFilter_Flags filter, void *channel_data, eAnim_ChannelType channel_type)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition anim_deps.cc:457
void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
Definition anim_deps.cc:350
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, const eAnimFilter_Flags filter_mode, void *data, const eAnimCont_Types datatype)
local_group_size(16, 16) .push_constant(Type b
#define printf
#define G(x, y, z)
void base_select(Base *base, eObjectSelect_Mode mode)
void base_activate_with_mode_exit_if_needed(bContext *C, Base *base)
bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr)
bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
Definition nla_edit.cc:213
bool nlaedit_is_tweakmode_on(bAnimContext *ac)
Definition nla_ops.cc:72
bool nlaop_poll_tweakmode_off(bContext *C)
Definition nla_ops.cc:28
static int nla_action_unlink_exec(bContext *C, wmOperator *op)
static int mouse_nla_tracks(bContext *C, bAnimContext *ac, int track_index, short selectmode)
Definition nla_tracks.cc:60
void NLA_OT_selected_objects_add(wmOperatorType *ot)
void NLA_OT_tracks_delete(wmOperatorType *ot)
void NLA_OT_tracks_add(wmOperatorType *ot)
static bool nla_action_unlink_poll(bContext *C)
static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void NLA_OT_action_unlink(wmOperatorType *ot)
static int nlatracks_pushdown_exec(bContext *C, wmOperator *op)
void NLA_OT_channels_click(wmOperatorType *ot)
void NLA_OT_action_pushdown(wmOperatorType *ot)
static int nlaedit_objects_add_exec(bContext *C, wmOperator *)
static int nlatracks_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
bool nlaedit_add_tracks_empty(bAnimContext *ac)
static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
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)
bAction * action
ListBase nla_tracks
short flag
struct Object * object
Definition DNA_ID.h:413
struct AnimData * adt
ID * owner_id
Definition RNA_types.hh:40
void * data
Definition RNA_types.hh:42
struct AnimData * adt
struct bDopeSheet * ads
SpaceLink * sl
eAnimCont_Types datatype
ViewLayer * view_layer
ARegion * region
AnimData * adt
eAnim_ChannelType type
eAnim_Update_Flags update
int mval[2]
Definition WM_types.hh:728
uint8_t modifier
Definition WM_types.hh:739
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
PropertyRNA * prop
Definition WM_types.hh:1092
StructRNA * srna
Definition WM_types.hh:1080
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4125