Blender  V3.3
nla_channels.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2009 Blender Foundation, Joshua Leung. All rights reserved. */
3 
8 #include <math.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 #include "DNA_anim_types.h"
14 #include "DNA_object_types.h"
15 #include "DNA_scene_types.h"
16 
17 #include "BLI_blenlib.h"
18 #include "BLI_utildefines.h"
19 
20 #include "BKE_anim_data.h"
21 #include "BKE_context.h"
22 #include "BKE_global.h"
23 #include "BKE_nla.h"
24 #include "BKE_report.h"
25 #include "BKE_scene.h"
26 #include "BKE_screen.h"
27 
28 #include "ED_anim_api.h"
29 #include "ED_keyframes_edit.h"
30 #include "ED_object.h"
31 #include "ED_screen.h"
32 
33 #include "RNA_access.h"
34 #include "RNA_define.h"
35 
36 #include "WM_api.h"
37 #include "WM_types.h"
38 
39 #include "UI_interface.h"
40 
41 #include "DEG_depsgraph.h"
42 #include "DEG_depsgraph_build.h"
43 
44 #include "UI_view2d.h"
45 
46 #include "nla_intern.h" /* own include */
47 
48 /* *********************************************** */
49 /* Operators for NLA channels-list which need to be different
50  * from the standard Animation Editor ones */
51 
52 /* ******************** Mouse-Click Operator *********************** */
53 /* Depending on the channel that was clicked on, the mouse click will activate whichever
54  * part of the channel is relevant.
55  *
56  * NOTE: eventually,
57  * this should probably be phased out when many of these things are replaced with buttons
58  * --> Most channels are now selection only.
59  */
60 
61 static int mouse_nla_channels(bContext *C, bAnimContext *ac, int channel_index, short selectmode)
62 {
63  ListBase anim_data = {NULL, NULL};
64  bAnimListElem *ale;
65  int filter;
66 
67  int notifierFlags = 0;
68 
69  /* get the channel that was clicked on */
70  /* filter channels */
73  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
74 
75  /* get channel from index */
76  ale = BLI_findlink(&anim_data, channel_index);
77  if (ale == NULL) {
78  /* channel not found */
79  if (G.debug & G_DEBUG) {
80  printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n",
81  channel_index);
82  }
83 
84  ANIM_animdata_freelist(&anim_data);
85  return 0;
86  }
87 
88  /* action to take depends on what channel we've got */
89  /* WARNING: must keep this in sync with the equivalent function in anim_channels_edit.c */
90  switch (ale->type) {
91  case ANIMTYPE_SCENE: {
92  Scene *sce = (Scene *)ale->data;
93  AnimData *adt = sce->adt;
94 
95  /* set selection status */
96  if (selectmode == SELECT_INVERT) {
97  /* swap select */
98  sce->flag ^= SCE_DS_SELECTED;
99  if (adt) {
100  adt->flag ^= ADT_UI_SELECTED;
101  }
102  }
103  else {
104  sce->flag |= SCE_DS_SELECTED;
105  if (adt) {
106  adt->flag |= ADT_UI_SELECTED;
107  }
108  }
109 
110  notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
111  break;
112  }
113  case ANIMTYPE_OBJECT: {
114  ViewLayer *view_layer = ac->view_layer;
115  Base *base = (Base *)ale->data;
116  Object *ob = base->object;
117  AnimData *adt = ob->adt;
118 
119  if (nlaedit_is_tweakmode_on(ac) == 0 && (base->flag & BASE_SELECTABLE)) {
120  /* set selection status */
121  if (selectmode == SELECT_INVERT) {
122  /* swap select */
124 
125  if (adt) {
126  adt->flag ^= ADT_UI_SELECTED;
127  }
128  }
129  else {
130  /* deselect all */
131  /* TODO: should this deselect all other types of channels too? */
132  LISTBASE_FOREACH (Base *, b, &view_layer->object_bases) {
134  if (b->object->adt) {
135  b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
136  }
137  }
138 
139  /* select object now */
141  if (adt) {
142  adt->flag |= ADT_UI_SELECTED;
143  }
144  }
145 
146  /* change active object - regardless of whether it is now selected [T37883] */
147  ED_object_base_activate_with_mode_exit_if_needed(C, base); /* adds notifier */
148 
149  if ((adt) && (adt->flag & ADT_UI_SELECTED)) {
150  adt->flag |= ADT_UI_ACTIVE;
151  }
152 
153  /* notifiers - channel was selected */
154  notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
155  }
156  break;
157  }
158  case ANIMTYPE_FILLACTD: /* Action Expander */
159  case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
160  case ANIMTYPE_DSLAM:
161  case ANIMTYPE_DSCAM:
163  case ANIMTYPE_DSCUR:
164  case ANIMTYPE_DSSKEY:
165  case ANIMTYPE_DSWOR:
166  case ANIMTYPE_DSNTREE:
167  case ANIMTYPE_DSPART:
168  case ANIMTYPE_DSMBALL:
169  case ANIMTYPE_DSARM:
170  case ANIMTYPE_DSMESH:
171  case ANIMTYPE_DSTEX:
172  case ANIMTYPE_DSLAT:
174  case ANIMTYPE_DSSPK:
175  case ANIMTYPE_DSGPENCIL:
176  case ANIMTYPE_PALETTE:
177  case ANIMTYPE_DSHAIR:
179  case ANIMTYPE_DSVOLUME:
180  case ANIMTYPE_DSSIMULATION: {
181  /* sanity checking... */
182  if (ale->adt) {
183  /* select/deselect */
184  if (selectmode == SELECT_INVERT) {
185  /* inverse selection status of this AnimData block only */
186  ale->adt->flag ^= ADT_UI_SELECTED;
187  }
188  else {
189  /* select AnimData block by itself */
191  ale->adt->flag |= ADT_UI_SELECTED;
192  }
193 
194  /* set active? */
195  if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) {
196  ale->adt->flag |= ADT_UI_ACTIVE;
197  }
198  }
199 
200  notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
201  break;
202  }
203  case ANIMTYPE_NLATRACK: {
204  NlaTrack *nlt = (NlaTrack *)ale->data;
205 
206  if (nlaedit_is_tweakmode_on(ac) == 0) {
207  /* set selection */
208  if (selectmode == SELECT_INVERT) {
209  /* inverse selection status of this F-Curve only */
210  nlt->flag ^= NLATRACK_SELECTED;
211  }
212  else {
213  /* select F-Curve by itself */
215  nlt->flag |= NLATRACK_SELECTED;
216  }
217 
218  /* if NLA-Track is selected now,
219  * make NLA-Track the 'active' one in the visible list */
220  if (nlt->flag & NLATRACK_SELECTED) {
222  }
223 
224  /* notifier flags - channel was selected */
225  notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
226  }
227  break;
228  }
229  case ANIMTYPE_NLAACTION: {
230  AnimData *adt = BKE_animdata_from_id(ale->id);
231 
232  /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
233  * - this is useful when there's no clear divider, and makes more sense in
234  * the case of users trying to use this to change actions
235  * - in tweak-mode, clicking here gets us out of tweak-mode, as changing selection
236  * while in tweak-mode is really evil!
237  * - we disable "solo" flags too, to make it easier to work with stashed actions
238  * with less trouble
239  */
240  if (nlaedit_is_tweakmode_on(ac)) {
241  /* Exit tweak-mode immediately. */
242  nlaedit_disable_tweakmode(ac, true);
243 
244  /* changes to NLA-Action occurred */
245  notifierFlags |= ND_NLA_ACTCHANGE;
246  ale->update |= ANIM_UPDATE_DEPS;
247  }
248  else {
249  /* select/deselect */
250  if (selectmode == SELECT_INVERT) {
251  /* inverse selection status of this AnimData block only */
252  adt->flag ^= ADT_UI_SELECTED;
253  }
254  else {
255  /* select AnimData block by itself */
257  adt->flag |= ADT_UI_SELECTED;
258  }
259 
260  /* set active? */
261  if (adt->flag & ADT_UI_SELECTED) {
262  adt->flag |= ADT_UI_ACTIVE;
263  }
264 
265  notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
266  }
267  break;
268  }
269  default:
270  if (G.debug & G_DEBUG) {
271  printf("Error: Invalid channel type in mouse_nla_channels()\n");
272  }
273  break;
274  }
275 
276  /* free channels */
277  ANIM_animdata_update(ac, &anim_data);
278  ANIM_animdata_freelist(&anim_data);
279 
280  /* return the notifier-flags set */
281  return notifierFlags;
282 }
283 
284 /* ------------------- */
285 
286 /* handle clicking */
288 {
289  bAnimContext ac;
290  SpaceNla *snla;
291  ARegion *region;
292  View2D *v2d;
293  int channel_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  snla = (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 channel user clicked in. */
317  UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
319  NLACHANNEL_STEP(snla),
320  0,
322  x,
323  y,
324  NULL,
325  &channel_index);
326 
327  /* handle mouse-click in the relevant channel then */
328  notifierFlags = mouse_nla_channels(C, &ac, channel_index, selectmode);
329 
330  /* set notifier that things have changed */
331  WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
332 
333  return OPERATOR_FINISHED;
334 }
335 
337 {
338  PropertyRNA *prop;
339 
340  /* identifiers */
341  ot->name = "Mouse Click on NLA Channels";
342  ot->idname = "NLA_OT_channels_click";
343  ot->description = "Handle clicks to select NLA channels";
344 
345  /* api callbacks */
348 
349  /* flags */
350  ot->flag = OPTYPE_UNDO;
351 
352  /* props */
353  prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); /* SHIFTKEY */
355 }
356 
357 /* *********************************************** */
358 /* Special Operators */
359 
360 /* ******************** Action Push Down ******************************** */
361 
363 {
364  bAnimContext ac;
365  ID *id = NULL;
366  AnimData *adt = NULL;
367  int channel_index = RNA_int_get(op->ptr, "channel_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 (channel_index == -1) {
376  PointerRNA adt_ptr = {NULL};
377 
378  /* active animdata block */
379  if (nla_panel_context(C, &adt_ptr, NULL, NULL) == 0 || (adt_ptr.data == NULL)) {
380  BKE_report(op->reports,
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 = adt_ptr.data;
390  }
391  else {
392  /* indexed channel */
393  ListBase anim_data = {NULL, NULL};
394  bAnimListElem *ale;
395  int filter;
396 
397  /* filter channels */
400  ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
401 
402  /* get channel from index */
403  ale = BLI_findlink(&anim_data, channel_index);
404  if (ale == NULL) {
405  BKE_reportf(op->reports, RPT_ERROR, "No animation channel found at index %d", channel_index);
406  ANIM_animdata_freelist(&anim_data);
407  return OPERATOR_CANCELLED;
408  }
409  if (ale->type != ANIMTYPE_NLAACTION) {
410  BKE_reportf(op->reports,
411  RPT_ERROR,
412  "Animation channel at index %d is not a NLA 'Active Action' channel",
413  channel_index);
414  ANIM_animdata_freelist(&anim_data);
415  return OPERATOR_CANCELLED;
416  }
417 
418  /* grab AnimData from the channel */
419  adt = ale->adt;
420  id = ale->id;
421 
422  /* we don't need anything here anymore, so free it all */
423  ANIM_animdata_freelist(&anim_data);
424  }
425 
426  /* double-check that we are free to push down here... */
427  if (adt == NULL) {
428  BKE_report(op->reports, RPT_WARNING, "Internal Error - AnimData block is not valid");
429  return OPERATOR_CANCELLED;
430  }
431  if (nlaedit_is_tweakmode_on(&ac)) {
432  BKE_report(op->reports,
433  RPT_WARNING,
434  "Cannot push down actions while tweaking a strip's action, exit tweak mode first");
435  return OPERATOR_CANCELLED;
436  }
437  if (adt->action == NULL) {
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  struct 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. */
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 */
472  ot->prop = RNA_def_int(ot->srna,
473  "channel_index",
474  -1,
475  -1,
476  INT_MAX,
477  "Channel Index",
478  "Index of NLA action channel 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, NULL, NULL) && (adt_ptr.data != NULL));
491  }
492 
493  /* something failed... */
494  return false;
495 }
496 
498 {
499  PointerRNA adt_ptr;
500  AnimData *adt;
501 
502  /* check context and also validity of pointer */
503  if (!nla_panel_context(C, &adt_ptr, NULL, NULL)) {
504  return OPERATOR_CANCELLED;
505  }
506 
507  /* get animdata */
508  adt = adt_ptr.data;
509  if (adt == NULL) {
510  return OPERATOR_CANCELLED;
511  }
512 
513  /* do unlinking */
514  if (adt->action) {
515  bool force_delete = RNA_boolean_get(op->ptr, "force_delete");
516  ED_animedit_unlink_action(C, adt_ptr.owner_id, adt, adt->action, op->reports, force_delete);
517  }
518 
519  return OPERATOR_FINISHED;
520 }
521 
522 static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *event)
523 {
524  /* NOTE: this is hardcoded to match the behavior for the unlink button
525  * (in interface_templates.c) */
526  RNA_boolean_set(op->ptr, "force_delete", event->modifier & KM_SHIFT);
527  return nla_action_unlink_exec(C, op);
528 }
529 
531 {
532  PropertyRNA *prop;
533 
534  /* identifiers */
535  ot->name = "Unlink Action";
536  ot->idname = "NLA_OT_action_unlink";
537  ot->description = "Unlink this action from the active action slot (and/or exit Tweak Mode)";
538 
539  /* callbacks */
543 
544  /* properties */
545  prop = RNA_def_boolean(ot->srna,
546  "force_delete",
547  false,
548  "Force Delete",
549  "Clear Fake User and remove copy stashed in this data-block's NLA stack");
551 }
552 
553 /* ******************** Add Tracks Operator ***************************** */
554 /* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
555 
556 bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
557 {
558  ListBase anim_data = {NULL, NULL};
559  bAnimListElem *ale;
560  int filter;
561  AnimData *lastAdt = NULL;
562  bool added = false;
563 
564  /* get a list of the (selected) NLA Tracks being shown in the NLA */
567  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
568 
569  /* add tracks... */
570  for (ale = anim_data.first; ale; ale = ale->next) {
571  if (ale->type == ANIMTYPE_NLATRACK) {
572  NlaTrack *nlt = (NlaTrack *)ale->data;
573  AnimData *adt = ale->adt;
574 
575  const bool is_liboverride = ID_IS_OVERRIDE_LIBRARY(ale->id);
576 
577  /* check if just adding a new track above this one,
578  * or whether we're adding a new one to the top of the stack that this one belongs to
579  */
580  if (above_sel) {
581  /* just add a new one above this one */
582  BKE_nlatrack_add(adt, nlt, is_liboverride);
583  ale->update = ANIM_UPDATE_DEPS;
584  added = true;
585  }
586  else if ((lastAdt == NULL) || (adt != lastAdt)) {
587  /* add one track to the top of the owning AnimData's stack,
588  * then don't add anymore to this stack */
589  BKE_nlatrack_add(adt, NULL, is_liboverride);
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 = {NULL, NULL};
607  bAnimListElem *ale;
608  int filter;
609  bool added = false;
610 
611  /* get a list of the selected AnimData blocks in the NLA */
614  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
615 
616  /* check if selected AnimData blocks are empty, and add tracks if so... */
617  for (ale = anim_data.first; ale; ale = ale->next) {
618  AnimData *adt = ale->adt;
619 
620  /* sanity check */
622 
623  /* ensure it is empty */
624  if (BLI_listbase_is_empty(&adt->nla_tracks)) {
625  /* add new track to this AnimData block then */
627  ale->update = ANIM_UPDATE_DEPS;
628  added = true;
629  }
630  }
631 
632  /* cleanup */
633  ANIM_animdata_update(ac, &anim_data);
634  ANIM_animdata_freelist(&anim_data);
635 
636  return added;
637 }
638 
639 /* ----- */
640 
642 {
643  bAnimContext ac;
644  bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
645  bool op_done = false;
646 
647  /* get editor data */
648  if (ANIM_animdata_get_context(C, &ac) == 0) {
649  return OPERATOR_CANCELLED;
650  }
651 
652  /* perform adding in two passes - existing first so that we don't double up for empty */
653  op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
654  op_done |= nlaedit_add_tracks_empty(&ac);
655 
656  /* done? */
657  if (op_done) {
659 
660  /* set notifier that things have changed */
662 
663  /* done */
664  return OPERATOR_FINISHED;
665  }
666 
667  /* failed to add any tracks */
668  BKE_report(
669  op->reports, RPT_WARNING, "Select an existing NLA Track or an empty action line first");
670 
671  /* not done */
672  return OPERATOR_CANCELLED;
673 }
674 
676 {
677  /* identifiers */
678  ot->name = "Add Tracks";
679  ot->idname = "NLA_OT_tracks_add";
680  ot->description = "Add NLA-Tracks above/after the selected tracks";
681 
682  /* api callbacks */
685 
686  /* flags */
688 
689  /* properties */
691  "above_selected",
692  0,
693  "Above Selected",
694  "Add a new NLA Track above every existing selected one");
695 }
696 
697 /* ******************** Delete Tracks Operator ***************************** */
698 /* Delete selected NLA Tracks */
699 
701 {
702  bAnimContext ac;
703 
704  ListBase anim_data = {NULL, NULL};
705  bAnimListElem *ale;
706  int filter;
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, ac.datatype);
717 
718  /* delete tracks */
719  for (ale = anim_data.first; ale; ale = ale->next) {
720  if (ale->type == ANIMTYPE_NLATRACK) {
721  NlaTrack *nlt = (NlaTrack *)ale->data;
722  AnimData *adt = ale->adt;
723 
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 */
737  BKE_nlatrack_free(&adt->nla_tracks, nlt, true);
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  SpaceNla *snla;
785 
786  /* get editor data */
787  if (ANIM_animdata_get_context(C, &ac) == 0) {
788  return OPERATOR_CANCELLED;
789  }
790 
791  /* ensure that filters are set so that the effect will be immediately visible */
792  snla = (SpaceNla *)ac.sl;
793  if (snla && snla->ads) {
795  }
796 
797  /* operate on selected objects... */
798  CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
799  /* ensure that object has AnimData... that's all */
800  BKE_animdata_ensure_id(&ob->id);
801  }
802  CTX_DATA_END;
803 
804  /* set notifier that things have changed */
806 
807  /* done */
808  return OPERATOR_FINISHED;
809 }
810 
812 {
813  /* identifiers */
814  ot->name = "Include Selected Objects";
815  ot->idname = "NLA_OT_selected_objects_add";
816  ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
817 
818  /* api callbacks */
821 
822  /* flags */
824 }
825 
826 /* *********************************************** */
struct AnimData * BKE_animdata_ensure_id(struct ID *id)
Definition: anim_data.c:90
struct AnimData * BKE_animdata_from_id(const struct ID *id)
#define CTX_DATA_BEGIN(C, Type, instance, member)
Definition: BKE_context.h:269
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
#define CTX_DATA_END
Definition: BKE_context.h:278
@ G_DEBUG
Definition: BKE_global.h:174
bool BKE_nlatrack_is_nonlocal_in_liboverride(const struct ID *id, const struct NlaTrack *nlt)
void BKE_nla_action_pushdown(struct AnimData *adt, bool is_liboverride)
Definition: nla.c:1909
struct NlaTrack * BKE_nlatrack_add(struct AnimData *adt, struct NlaTrack *prev, bool is_liboverride)
Definition: nla.c:353
void BKE_nlatrack_free(ListBase *tracks, struct NlaTrack *nlt, bool do_id_user)
Definition: nla.c:103
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.c:83
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define UNUSED(x)
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_ANIMATION
Definition: DNA_ID.h:794
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
@ ADS_FILTER_NLA_NOACT
@ ADT_NLA_SOLO_TRACK
@ ADT_UI_ACTIVE
@ ADT_UI_SELECTED
@ NLATRACK_SOLO
@ NLATRACK_SELECTED
@ BASE_SELECTABLE
Object is a sort of wrapper for general info.
#define SCE_DS_SELECTED
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_animedit_unlink_action(struct bContext *C, struct ID *id, struct AnimData *adt, struct bAction *act, struct ReportList *reports, bool force_delete)
Definition: action_data.c:550
@ ACHANNEL_SETFLAG_CLEAR
Definition: ED_anim_api.h:550
@ ANIMTYPE_DSSPK
Definition: ED_anim_api.h:222
@ ANIMTYPE_DSTEX
Definition: ED_anim_api.h:219
@ ANIMTYPE_DSNTREE
Definition: ED_anim_api.h:214
@ ANIMTYPE_DSMBALL
Definition: ED_anim_api.h:216
@ ANIMTYPE_DSCAM
Definition: ED_anim_api.h:209
@ ANIMTYPE_DSPOINTCLOUD
Definition: ED_anim_api.h:226
@ ANIMTYPE_DSPART
Definition: ED_anim_api.h:215
@ ANIMTYPE_DSLINESTYLE
Definition: ED_anim_api.h:221
@ ANIMTYPE_DSCUR
Definition: ED_anim_api.h:211
@ ANIMTYPE_SCENE
Definition: ED_anim_api.h:196
@ ANIMTYPE_DSARM
Definition: ED_anim_api.h:217
@ ANIMTYPE_DSSIMULATION
Definition: ED_anim_api.h:228
@ ANIMTYPE_DSGPENCIL
Definition: ED_anim_api.h:223
@ ANIMTYPE_DSLAT
Definition: ED_anim_api.h:220
@ ANIMTYPE_NLAACTION
Definition: ED_anim_api.h:239
@ ANIMTYPE_DSMAT
Definition: ED_anim_api.h:207
@ ANIMTYPE_DSCACHEFILE
Definition: ED_anim_api.h:210
@ ANIMTYPE_DSVOLUME
Definition: ED_anim_api.h:227
@ ANIMTYPE_DSLAM
Definition: ED_anim_api.h:208
@ ANIMTYPE_PALETTE
Definition: ED_anim_api.h:241
@ ANIMTYPE_FILLACTD
Definition: ED_anim_api.h:204
@ ANIMTYPE_OBJECT
Definition: ED_anim_api.h:197
@ ANIMTYPE_DSMESH
Definition: ED_anim_api.h:218
@ ANIMTYPE_NLATRACK
Definition: ED_anim_api.h:238
@ ANIMTYPE_DSWOR
Definition: ED_anim_api.h:213
@ ANIMTYPE_DSSKEY
Definition: ED_anim_api.h:212
@ ANIMTYPE_DSHAIR
Definition: ED_anim_api.h:225
#define NLACHANNEL_STEP(snla)
Definition: ED_anim_api.h:466
#define NLACHANNEL_NAMEWIDTH
Definition: ED_anim_api.h:472
@ ANIM_UPDATE_DEPS
Definition: ED_anim_api.h:268
#define NLACHANNEL_FIRST_TOP(ac)
Definition: ED_anim_api.h:460
@ ANIMFILTER_ANIMDATA
Definition: ED_anim_api.h:322
@ ANIMFILTER_DATA_VISIBLE
Definition: ED_anim_api.h:292
@ ANIMFILTER_LIST_VISIBLE
Definition: ED_anim_api.h:295
@ ANIMFILTER_LIST_CHANNELS
Definition: ED_anim_api.h:300
@ ANIMFILTER_NODUPLIS
Definition: ED_anim_api.h:325
@ ANIMFILTER_FCURVESONLY
Definition: ED_anim_api.h:328
@ ANIMFILTER_SEL
Definition: ED_anim_api.h:308
@ SELECT_INVERT
@ SELECT_REPLACE
void ED_object_base_activate_with_mode_exit_if_needed(struct bContext *C, struct Base *base)
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode)
Definition: object_select.c:76
@ BA_DESELECT
Definition: ED_object.h:154
@ BA_INVERT
Definition: ED_object.h:156
@ BA_SELECT
Definition: ED_object.h:155
bool ED_operator_nla_active(struct bContext *C)
Definition: screen_ops.c:349
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
#define C
Definition: RandGen.cpp:25
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:1619
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define ND_NLA_ACTCHANGE
Definition: WM_types.h:446
#define NC_ANIMATION
Definition: WM_types.h:338
#define NA_ADDED
Definition: WM_types.h:525
#define NA_EDITED
Definition: WM_types.h:523
#define NA_REMOVED
Definition: WM_types.h:526
#define ND_NLA
Definition: WM_types.h:445
@ KM_SHIFT
Definition: WM_types.h:238
#define ND_ANIMCHAN
Definition: WM_types.h:444
#define NA_SELECTED
Definition: WM_types.h:528
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.c:397
void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
Definition: anim_deps.c:302
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
Definition: anim_filter.c:379
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
Definition: anim_filter.c:3447
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
#define G(x, y, z)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr)
Definition: nla_buttons.c:59
static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: nla_channels.c:287
static int nla_action_unlink_exec(bContext *C, wmOperator *op)
Definition: nla_channels.c:497
void NLA_OT_selected_objects_add(wmOperatorType *ot)
Definition: nla_channels.c:811
void NLA_OT_tracks_delete(wmOperatorType *ot)
Definition: nla_channels.c:755
void NLA_OT_tracks_add(wmOperatorType *ot)
Definition: nla_channels.c:675
static int mouse_nla_channels(bContext *C, bAnimContext *ac, int channel_index, short selectmode)
Definition: nla_channels.c:61
static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
Definition: nla_channels.c:700
static bool nla_action_unlink_poll(bContext *C)
Definition: nla_channels.c:486
static int nla_action_unlink_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: nla_channels.c:522
void NLA_OT_action_unlink(wmOperatorType *ot)
Definition: nla_channels.c:530
void NLA_OT_channels_click(wmOperatorType *ot)
Definition: nla_channels.c:336
void NLA_OT_action_pushdown(wmOperatorType *ot)
Definition: nla_channels.c:457
static int nlachannels_pushdown_exec(bContext *C, wmOperator *op)
Definition: nla_channels.c:362
bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
Definition: nla_channels.c:556
bool nlaedit_add_tracks_empty(bAnimContext *ac)
Definition: nla_channels.c:604
static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
Definition: nla_channels.c:641
static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
Definition: nla_channels.c:781
bool nlaedit_disable_tweakmode(bAnimContext *ac, bool do_solo)
Definition: nla_edit.c:208
bool nlaedit_is_tweakmode_on(bAnimContext *ac)
Definition: nla_ops.c:72
bool nlaop_poll_tweakmode_off(bContext *C)
Definition: nla_ops.c:28
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
bAction * action
ListBase nla_tracks
short flag
struct Object * object
Definition: DNA_ID.h:368
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
short flag
struct AnimData * adt
struct bDopeSheet * ads
ListBase object_bases
struct ARegion * region
Definition: ED_anim_api.h:76
short datatype
Definition: ED_anim_api.h:62
void * data
Definition: ED_anim_api.h:60
struct ViewLayer * view_layer
Definition: ED_anim_api.h:86
struct Main * bmain
Definition: ED_anim_api.h:82
struct SpaceLink * sl
Definition: ED_anim_api.h:74
struct bAnimListElem * next
Definition: ED_anim_api.h:127
struct AnimData * adt
Definition: ED_anim_api.h:162
struct ID * id
Definition: ED_anim_api.h:160
int mval[2]
Definition: WM_types.h:684
uint8_t modifier
Definition: WM_types.h:693
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
PropertyRNA * prop
Definition: WM_types.h:981
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition: wm_files.c:3479