Blender  V2.93
action_edit.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <float.h>
25 #include <math.h>
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "BLI_blenlib.h"
30 #include "BLI_math.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BLT_translation.h"
34 
35 #include "DNA_anim_types.h"
36 #include "DNA_gpencil_types.h"
37 #include "DNA_key_types.h"
38 #include "DNA_mask_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41 
42 #include "RNA_access.h"
43 #include "RNA_define.h"
44 #include "RNA_enum_types.h"
45 
46 #include "BKE_action.h"
47 #include "BKE_animsys.h"
48 #include "BKE_context.h"
49 #include "BKE_fcurve.h"
50 #include "BKE_global.h"
51 #include "BKE_gpencil.h"
52 #include "BKE_key.h"
53 #include "BKE_nla.h"
54 #include "BKE_report.h"
55 
56 #include "UI_view2d.h"
57 
58 #include "ED_anim_api.h"
59 #include "ED_gpencil.h"
60 #include "ED_keyframes_edit.h"
61 #include "ED_keyframing.h"
62 #include "ED_markers.h"
63 #include "ED_mask.h"
64 #include "ED_screen.h"
65 
66 #include "WM_api.h"
67 #include "WM_types.h"
68 
69 #include "UI_interface.h"
70 
71 #include "action_intern.h"
72 
73 /* ************************************************************************** */
74 /* POSE MARKERS STUFF */
75 
76 /* *************************** Localize Markers ***************************** */
77 
78 /* ensure that there is:
79  * 1) an active action editor
80  * 2) that the mode will have an active action available
81  * 3) that the set of markers being shown are the scene markers, not the list we're merging
82  * 4) that there are some selected markers
83  */
85 {
87 
88  /* 1) */
89  if (sact == NULL) {
90  return 0;
91  }
92 
93  /* 2) */
94  if (ELEM(sact->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) == 0) {
95  return 0;
96  }
97  if (sact->action == NULL) {
98  return 0;
99  }
100 
101  /* 3) */
102  if (sact->flag & SACTION_POSEMARKERS_SHOW) {
103  return 0;
104  }
105 
106  /* 4) */
108 }
109 
111 {
113 
115  bAction *act = (sact) ? sact->action : NULL;
116 
117  TimeMarker *marker, *markern = NULL;
118 
119  /* sanity checks */
120  if (ELEM(NULL, markers, act)) {
121  return OPERATOR_CANCELLED;
122  }
123 
124  /* migrate markers */
125  for (marker = markers->first; marker; marker = markern) {
126  markern = marker->next;
127 
128  /* move if marker is selected */
129  if (marker->flag & SELECT) {
130  BLI_remlink(markers, marker);
131  BLI_addtail(&act->markers, marker);
132  }
133  }
134 
135  /* Now enable the "show posemarkers only" setting,
136  * so that we can see that something did happen */
138 
139  /* notifiers - both sets, as this change affects both */
142 
143  return OPERATOR_FINISHED;
144 }
145 
147 {
148  /* identifiers */
149  ot->name = "Make Markers Local";
150  ot->idname = "ACTION_OT_markers_make_local";
151  ot->description = "Move selected scene markers to the active Action as local 'pose' markers";
152 
153  /* callbacks */
156 
157  /* flags */
159 }
160 
161 /* ************************************************************************** */
162 /* KEYFRAME-RANGE STUFF */
163 
164 /* *************************** Calculate Range ************************** */
165 
166 /* Get the min/max keyframes*/
167 static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel)
168 {
169  ListBase anim_data = {NULL, NULL};
170  bAnimListElem *ale;
171  int filter;
172  bool found = false;
173 
174  /* get data to filter, from Action or Dopesheet */
175  /* XXX: what is sel doing here?!
176  * Commented it, was breaking things (eg. the "auto preview range" tool). */
178  ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_SEL */ /*| ANIMFILTER_CURVESONLY*/ |
180  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
181 
182  /* set large values to try to override */
183  *min = 999999999.0f;
184  *max = -999999999.0f;
185 
186  /* check if any channels to set range with */
187  if (anim_data.first) {
188  /* go through channels, finding max extents */
189  for (ale = anim_data.first; ale; ale = ale->next) {
190  AnimData *adt = ANIM_nla_mapping_get(ac, ale);
191  if (ale->datatype == ALE_GPFRAME) {
192  bGPDlayer *gpl = ale->data;
193  bGPDframe *gpf;
194 
195  /* find gp-frame which is less than or equal to cframe */
196  for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
197  const float framenum = (float)gpf->framenum;
198  *min = min_ff(*min, framenum);
199  *max = max_ff(*max, framenum);
200  found = true;
201  }
202  }
203  else if (ale->datatype == ALE_MASKLAY) {
204  MaskLayer *masklay = ale->data;
205  MaskLayerShape *masklay_shape;
206 
207  /* find mask layer which is less than or equal to cframe */
208  for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
209  masklay_shape = masklay_shape->next) {
210  const float framenum = (float)masklay_shape->frame;
211  *min = min_ff(*min, framenum);
212  *max = max_ff(*max, framenum);
213  found = true;
214  }
215  }
216  else {
217  FCurve *fcu = (FCurve *)ale->key_data;
218  float tmin, tmax;
219 
220  /* get range and apply necessary scaling before processing */
221  if (BKE_fcurve_calc_range(fcu, &tmin, &tmax, onlySel, false)) {
222 
223  if (adt) {
224  tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
225  tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
226  }
227 
228  /* Try to set cur using these values,
229  * if they're more extreme than previously set values. */
230  *min = min_ff(*min, tmin);
231  *max = max_ff(*max, tmax);
232  found = true;
233  }
234  }
235  }
236 
237  if (fabsf(*max - *min) < 0.001f) {
238  *min -= 0.0005f;
239  *max += 0.0005f;
240  }
241 
242  /* free memory */
243  ANIM_animdata_freelist(&anim_data);
244  }
245  else {
246  /* set default range */
247  if (ac->scene) {
248  *min = (float)ac->scene->r.sfra;
249  *max = (float)ac->scene->r.efra;
250  }
251  else {
252  *min = -5;
253  *max = 100;
254  }
255  }
256 
257  return found;
258 }
259 
260 /* ****************** Automatic Preview-Range Operator ****************** */
261 
263 {
264  bAnimContext ac;
265  Scene *scene;
266  float min, max;
267 
268  /* get editor data */
269  if (ANIM_animdata_get_context(C, &ac) == 0) {
270  return OPERATOR_CANCELLED;
271  }
272  if (ac.scene == NULL) {
273  return OPERATOR_CANCELLED;
274  }
275 
276  scene = ac.scene;
277 
278  /* set the range directly */
279  get_keyframe_extents(&ac, &min, &max, false);
281  scene->r.psfra = floorf(min);
282  scene->r.pefra = ceilf(max);
283 
284  if (scene->r.psfra == scene->r.pefra) {
285  scene->r.pefra = scene->r.psfra + 1;
286  }
287 
288  /* set notifier that things have changed */
289  /* XXX err... there's nothing for frame ranges yet, but this should do fine too */
291 
292  return OPERATOR_FINISHED;
293 }
294 
296 {
297  /* identifiers */
298  ot->name = "Auto-Set Preview Range";
299  ot->idname = "ACTION_OT_previewrange_set";
300  ot->description = "Set Preview Range based on extents of selected Keyframes";
301 
302  /* api callbacks */
305 
306  /* flags */
308 }
309 
310 /* ****************** View-All Operator ****************** */
311 
319 static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *r_min, float *r_max)
320 {
321  ListBase anim_data = {NULL, NULL};
322  bAnimListElem *ale;
323  int filter;
324 
325  /* NOTE: not bool, since we want prioritize individual channels over expanders. */
326  short found = 0;
327 
328  /* get all items - we need to do it this way */
330  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
331 
332  /* loop through all channels, finding the first one that's selected */
333  float ymax = ACHANNEL_FIRST_TOP(ac);
334 
335  for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac)) {
337 
338  /* must be selected... */
339  if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) &&
341  /* update best estimate */
342  *r_min = ymax - ACHANNEL_HEIGHT(ac);
343  *r_max = ymax;
344 
345  /* is this high enough priority yet? */
346  found = acf->channel_role;
347 
348  /* only stop our search when we've found an actual channel
349  * - data-block expanders get less priority so that we don't abort prematurely
350  */
351  if (found == ACHANNEL_ROLE_CHANNEL) {
352  break;
353  }
354  }
355  }
356 
357  /* free all temp data */
358  ANIM_animdata_freelist(&anim_data);
359 
360  return (found != 0);
361 }
362 
363 static int actkeys_viewall(bContext *C, const bool only_sel)
364 {
365  bAnimContext ac;
366  View2D *v2d;
367  float extra, min, max;
368  bool found;
369 
370  /* get editor data */
371  if (ANIM_animdata_get_context(C, &ac) == 0) {
372  return OPERATOR_CANCELLED;
373  }
374  v2d = &ac.region->v2d;
375 
376  /* set the horizontal range, with an extra offset so that the extreme keys will be in view */
377  found = get_keyframe_extents(&ac, &min, &max, only_sel);
378 
379  if (only_sel && (found == false)) {
380  return OPERATOR_CANCELLED;
381  }
382 
383  if (fabsf(max - min) < 1.0f) {
384  /* Exception - center the single keyfrme */
385  float xwidth = BLI_rctf_size_x(&v2d->cur);
386 
387  v2d->cur.xmin = min - xwidth / 2.0f;
388  v2d->cur.xmax = max + xwidth / 2.0f;
389  }
390  else {
391  /* Normal case - stretch the two keyframes out to fill the space, with extra spacing */
392  v2d->cur.xmin = min;
393  v2d->cur.xmax = max;
394 
395  extra = 0.125f * BLI_rctf_size_x(&v2d->cur);
396  v2d->cur.xmin -= extra;
397  v2d->cur.xmax += extra;
398  }
399 
400  /* set vertical range */
401  if (only_sel == false) {
402  /* view all -> the summary channel is usually the shows everything,
403  * and resides right at the top... */
404  v2d->cur.ymax = 0.0f;
405  v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
406  }
407  else {
408  /* locate first selected channel (or the active one), and frame those */
409  float ymin = v2d->cur.ymin;
410  float ymax = v2d->cur.ymax;
411 
412  if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) {
413  /* recenter the view so that this range is in the middle */
414  float ymid = (ymax - ymin) / 2.0f + ymin;
415  float x_center;
416 
417  UI_view2d_center_get(v2d, &x_center, NULL);
418  UI_view2d_center_set(v2d, x_center, ymid);
419  }
420  }
421 
422  /* do View2D syncing */
424 
425  /* just redraw this view */
427 
428  return OPERATOR_FINISHED;
429 }
430 
431 /* ......... */
432 
434 {
435  /* whole range */
436  return actkeys_viewall(C, false);
437 }
438 
440 {
441  /* only selected */
442  return actkeys_viewall(C, true);
443 }
444 
445 /* ......... */
446 
448 {
449  /* identifiers */
450  ot->name = "Frame All";
451  ot->idname = "ACTION_OT_view_all";
452  ot->description = "Reset viewable area to show full keyframe range";
453 
454  /* api callbacks */
457 
458  /* flags */
459  ot->flag = 0;
460 }
461 
463 {
464  /* identifiers */
465  ot->name = "Frame Selected";
466  ot->idname = "ACTION_OT_view_selected";
467  ot->description = "Reset viewable area to show selected keyframes range";
468 
469  /* api callbacks */
472 
473  /* flags */
474  ot->flag = 0;
475 }
476 
477 /* ****************** View-All Operator ****************** */
478 
480 {
481  const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
482  ANIM_center_frame(C, smooth_viewtx);
483 
484  return OPERATOR_FINISHED;
485 }
486 
488 {
489  /* identifiers */
490  ot->name = "Go to Current Frame";
491  ot->idname = "ACTION_OT_view_frame";
492  ot->description = "Move the view to the current frame";
493 
494  /* api callbacks */
497 
498  /* flags */
499  ot->flag = 0;
500 }
501 
502 /* ************************************************************************** */
503 /* GENERAL STUFF */
504 
505 /* ******************** Copy/Paste Keyframes Operator ************************* */
506 /* NOTE: the backend code for this is shared with the graph editor */
507 
509 {
510  ListBase anim_data = {NULL, NULL};
511  int filter, ok = 0;
512 
513  /* clear buffer first */
515 
516  /* filter data */
517  filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ |
519  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
520 
521  /* copy keyframes */
522  ok = copy_animedit_keys(ac, &anim_data);
523 
524  /* clean up */
525  ANIM_animdata_freelist(&anim_data);
526 
527  return ok;
528 }
529 
531  const eKeyPasteOffset offset_mode,
532  const eKeyMergeMode merge_mode,
533  bool flip)
534 {
535  ListBase anim_data = {NULL, NULL};
536  int filter, ok = 0;
537 
538  /* filter data
539  * - First time we try to filter more strictly, allowing only selected channels
540  * to allow copying animation between channels
541  * - Second time, we loosen things up if nothing was found the first time, allowing
542  * users to just paste keyframes back into the original curve again T31670.
543  */
545  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
546 
547  if (ANIM_animdata_filter(ac, &anim_data, filter | ANIMFILTER_SEL, ac->data, ac->datatype) == 0) {
548  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
549  }
550 
551  /* paste keyframes */
552  ok = paste_animedit_keys(ac, &anim_data, offset_mode, merge_mode, flip);
553 
554  /* clean up */
555  ANIM_animdata_freelist(&anim_data);
556 
557  return ok;
558 }
559 
560 /* ------------------- */
561 
563 {
564  bAnimContext ac;
565 
566  /* get editor data */
567  if (ANIM_animdata_get_context(C, &ac) == 0) {
568  return OPERATOR_CANCELLED;
569  }
570 
571  /* copy keyframes */
572  if (ac.datatype == ANIMCONT_GPENCIL) {
573  if (ED_gpencil_anim_copybuf_copy(&ac) == false) {
574  /* Nothing got copied - An error about this should be been logged already */
575  return OPERATOR_CANCELLED;
576  }
577  }
578  else if (ac.datatype == ANIMCONT_MASK) {
579  /* FIXME... */
580  BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for mask mode");
581  return OPERATOR_CANCELLED;
582  }
583  else {
584  if (copy_action_keys(&ac)) {
585  BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
586  return OPERATOR_CANCELLED;
587  }
588  }
589 
590  return OPERATOR_FINISHED;
591 }
592 
594 {
595  /* identifiers */
596  ot->name = "Copy Keyframes";
597  ot->idname = "ACTION_OT_copy";
598  ot->description = "Copy selected keyframes to the copy/paste buffer";
599 
600  /* api callbacks */
603 
604  /* flags */
606 }
607 
609 {
610  bAnimContext ac;
611 
612  const eKeyPasteOffset offset_mode = RNA_enum_get(op->ptr, "offset");
613  const eKeyMergeMode merge_mode = RNA_enum_get(op->ptr, "merge");
614  const bool flipped = RNA_boolean_get(op->ptr, "flipped");
615 
616  /* get editor data */
617  if (ANIM_animdata_get_context(C, &ac) == 0) {
618  return OPERATOR_CANCELLED;
619  }
620 
621  /* ac.reports by default will be the global reports list, which won't show warnings */
622  ac.reports = op->reports;
623 
624  /* paste keyframes */
625  if (ac.datatype == ANIMCONT_GPENCIL) {
626  if (ED_gpencil_anim_copybuf_paste(&ac, offset_mode) == false) {
627  /* An error occurred - Reports should have been fired already */
628  return OPERATOR_CANCELLED;
629  }
630  }
631  else if (ac.datatype == ANIMCONT_MASK) {
632  /* FIXME... */
633  BKE_report(op->reports,
634  RPT_ERROR,
635  "Keyframe pasting is not available for grease pencil or mask mode");
636  return OPERATOR_CANCELLED;
637  }
638  else {
639  /* non-zero return means an error occurred while trying to paste */
640  if (paste_action_keys(&ac, offset_mode, merge_mode, flipped)) {
641  return OPERATOR_CANCELLED;
642  }
643  }
644 
645  /* Grease Pencil needs extra update to refresh the added keyframes. */
646  if (ac.datatype == ANIMCONT_GPENCIL) {
648  }
649  /* set notifier that keyframes have changed */
651 
652  return OPERATOR_FINISHED;
653 }
654 
656  wmOperatorType *UNUSED(op),
657  PointerRNA *ptr)
658 {
659  /* Custom description if the 'flipped' option is used. */
660  if (RNA_boolean_get(ptr, "flipped")) {
661  return BLI_strdup("Paste keyframes from mirrored bones if they exist");
662  }
663 
664  /* Use the default description in the other cases. */
665  return NULL;
666 }
667 
669 {
670  PropertyRNA *prop;
671  /* identifiers */
672  ot->name = "Paste Keyframes";
673  ot->idname = "ACTION_OT_paste";
674  ot->description =
675  "Paste keyframes from copy/paste buffer for the selected channels, starting on the current "
676  "frame";
677 
678  /* api callbacks */
679  // ot->invoke = WM_operator_props_popup; // better wait for action redo panel
683 
684  /* flags */
686 
687  /* props */
689  "offset",
692  "Offset",
693  "Paste time offset of keys");
695  "merge",
698  "Type",
699  "Method of merging pasted keys and existing");
700  prop = RNA_def_boolean(
701  ot->srna, "flipped", false, "Flipped", "Paste keyframes from mirrored bones if they exist");
703 }
704 
705 /* ******************** Insert Keyframes Operator ************************* */
706 
707 /* defines for insert keyframes tool */
709  {1, "ALL", 0, "All Channels", ""},
710  {2, "SEL", 0, "Only Selected Channels", ""},
711  /* XXX not in all cases. */
712  {3, "GROUP", 0, "In Active Group", ""},
713  {0, NULL, 0, NULL, NULL},
714 };
715 
716 /* this function is responsible for inserting new keyframes */
717 static void insert_action_keys(bAnimContext *ac, short mode)
718 {
719  ListBase anim_data = {NULL, NULL};
720  ListBase nla_cache = {NULL, NULL};
721  bAnimListElem *ale;
722  int filter;
723 
724  ReportList *reports = ac->reports;
725  Scene *scene = ac->scene;
727  eInsertKeyFlags flag;
728 
729  /* filter data */
731  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
732  if (mode == 2) {
734  }
735  else if (mode == 3) {
737  }
738 
739  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
740 
741  /* Init keyframing flag. */
742  flag = ANIM_get_keyframing_flags(scene, true);
743 
744  /* insert keyframes */
746  (float)CFRA);
747  for (ale = anim_data.first; ale; ale = ale->next) {
748  FCurve *fcu = (FCurve *)ale->key_data;
749 
750  /* Read value from property the F-Curve represents, or from the curve only?
751  * - ale->id != NULL:
752  * Typically, this means that we have enough info to try resolving the path.
753  *
754  * - ale->owner != NULL:
755  * If this is set, then the path may not be resolvable from the ID alone,
756  * so it's easier for now to just read the F-Curve directly.
757  * (TODO: add the full-blown PointerRNA relative parsing case here...)
758  */
759  if (ale->id && !ale->owner) {
761  reports,
762  ale->id,
763  NULL,
764  ((fcu->grp) ? (fcu->grp->name) : (NULL)),
765  fcu->rna_path,
766  fcu->array_index,
767  &anim_eval_context,
768  ts->keyframe_type,
769  &nla_cache,
770  flag);
771  }
772  else {
773  AnimData *adt = ANIM_nla_mapping_get(ac, ale);
774 
775  /* adjust current frame for NLA-scaling */
776  float cfra = anim_eval_context.eval_time;
777  if (adt) {
779  }
780 
781  const float curval = evaluate_fcurve(fcu, cfra);
782  insert_vert_fcurve(fcu, cfra, curval, ts->keyframe_type, 0);
783  }
784 
785  ale->update |= ANIM_UPDATE_DEFAULT;
786  }
787 
789 
790  ANIM_animdata_update(ac, &anim_data);
791  ANIM_animdata_freelist(&anim_data);
792 }
793 
794 /* this function is for inserting new grease pencil frames */
795 static void insert_gpencil_keys(bAnimContext *ac, short mode)
796 {
797  ListBase anim_data = {NULL, NULL};
798  bAnimListElem *ale;
799  int filter;
800 
801  Scene *scene = ac->scene;
803  eGP_GetFrame_Mode add_frame_mode;
804 
805  /* filter data */
808  if (mode == 2) {
810  }
811 
812  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
813 
814  /* add a copy or a blank frame? */
816  add_frame_mode = GP_GETFRAME_ADD_COPY; /* XXX: actframe may not be what we want? */
817  }
818  else {
819  add_frame_mode = GP_GETFRAME_ADD_NEW;
820  }
821 
822  /* Insert gp frames. */
823  bGPdata *gpd_old = NULL;
824  for (ale = anim_data.first; ale; ale = ale->next) {
825  bGPdata *gpd = (bGPdata *)ale->id;
826  bGPDlayer *gpl = (bGPDlayer *)ale->data;
827  BKE_gpencil_layer_frame_get(gpl, CFRA, add_frame_mode);
828  /* Check if the gpd changes to tag only once. */
829  if (gpd != gpd_old) {
830  BKE_gpencil_tag(gpd);
831  gpd_old = gpd;
832  }
833  }
834 
835  ANIM_animdata_update(ac, &anim_data);
836  ANIM_animdata_freelist(&anim_data);
837 }
838 
839 /* ------------------- */
840 
842 {
843  bAnimContext ac;
844  short mode;
845 
846  /* get editor data */
847  if (ANIM_animdata_get_context(C, &ac) == 0) {
848  return OPERATOR_CANCELLED;
849  }
850 
851  if (ac.datatype == ANIMCONT_MASK) {
852  BKE_report(op->reports, RPT_ERROR, "Insert Keyframes is not yet implemented for this mode");
853  return OPERATOR_CANCELLED;
854  }
855 
856  /* what channels to affect? */
857  mode = RNA_enum_get(op->ptr, "type");
858 
859  /* insert keyframes */
860  if (ac.datatype == ANIMCONT_GPENCIL) {
861  insert_gpencil_keys(&ac, mode);
862  }
863  else {
864  insert_action_keys(&ac, mode);
865  }
866 
867  /* set notifier that keyframes have changed */
868  if (ac.datatype == ANIMCONT_GPENCIL) {
870  }
872 
873  return OPERATOR_FINISHED;
874 }
875 
877 {
878  /* identifiers */
879  ot->name = "Insert Keyframes";
880  ot->idname = "ACTION_OT_keyframe_insert";
881  ot->description = "Insert keyframes for the specified channels";
882 
883  /* api callbacks */
887 
888  /* flags */
890 
891  /* id-props */
892  ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_insertkey_types, 0, "Type", "");
893 }
894 
895 /* ******************** Duplicate Keyframes Operator ************************* */
896 
898 {
899  ListBase anim_data = {NULL, NULL};
900  bAnimListElem *ale;
901  int filter;
902 
903  /* filter data */
907  }
908  else {
910  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
911  }
912  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
913 
914  /* loop through filtered data and delete selected keys */
915  for (ale = anim_data.first; ale; ale = ale->next) {
918  }
919  else if (ale->type == ANIMTYPE_GPLAYER) {
921  }
922  else if (ale->type == ANIMTYPE_MASKLAYER) {
924  }
925  else {
926  BLI_assert(0);
927  }
928 
929  ale->update |= ANIM_UPDATE_DEFAULT;
930  }
931 
932  ANIM_animdata_update(ac, &anim_data);
933  ANIM_animdata_freelist(&anim_data);
934 }
935 
936 /* ------------------- */
937 
939 {
940  bAnimContext ac;
941 
942  /* get editor data */
943  if (ANIM_animdata_get_context(C, &ac) == 0) {
944  return OPERATOR_CANCELLED;
945  }
946 
947  /* duplicate keyframes */
949 
950  /* set notifier that keyframes have changed */
952 
953  return OPERATOR_FINISHED;
954 }
955 
957 {
958  /* identifiers */
959  ot->name = "Duplicate Keyframes";
960  ot->idname = "ACTION_OT_duplicate";
961  ot->description = "Make a copy of all selected keyframes";
962 
963  /* api callbacks */
966 
967  /* flags */
969 }
970 
971 /* ******************** Delete Keyframes Operator ************************* */
972 
974 {
975  ListBase anim_data = {NULL, NULL};
976  bAnimListElem *ale;
977  int filter;
978  bool changed_final = false;
979 
980  /* filter data */
984  }
985  else {
987  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
988  }
989  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
990 
991  /* loop through filtered data and delete selected keys */
992  for (ale = anim_data.first; ale; ale = ale->next) {
993  bool changed = false;
994 
995  if (ale->type == ANIMTYPE_GPLAYER) {
996  changed = ED_gpencil_layer_frames_delete((bGPDlayer *)ale->data);
997  }
998  else if (ale->type == ANIMTYPE_MASKLAYER) {
999  changed = ED_masklayer_frames_delete((MaskLayer *)ale->data);
1000  }
1001  else {
1002  FCurve *fcu = (FCurve *)ale->key_data;
1003  AnimData *adt = ale->adt;
1004 
1005  /* delete selected keyframes only */
1006  changed = delete_fcurve_keys(fcu);
1007 
1008  /* Only delete curve too if it won't be doing anything anymore */
1009  if (BKE_fcurve_is_empty(fcu)) {
1010  ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
1011  ale->key_data = NULL;
1012  }
1013  }
1014 
1015  if (changed) {
1016  ale->update |= ANIM_UPDATE_DEFAULT;
1017  changed_final = true;
1018  }
1019  }
1020 
1021  ANIM_animdata_update(ac, &anim_data);
1022  ANIM_animdata_freelist(&anim_data);
1023 
1024  return changed_final;
1025 }
1026 
1027 /* ------------------- */
1028 
1030 {
1031  bAnimContext ac;
1032 
1033  /* get editor data */
1034  if (ANIM_animdata_get_context(C, &ac) == 0) {
1035  return OPERATOR_CANCELLED;
1036  }
1037 
1038  /* delete keyframes */
1039  if (!delete_action_keys(&ac)) {
1040  return OPERATOR_CANCELLED;
1041  }
1042 
1043  /* set notifier that keyframes have changed */
1045 
1046  return OPERATOR_FINISHED;
1047 }
1048 
1050 {
1051  /* identifiers */
1052  ot->name = "Delete Keyframes";
1053  ot->idname = "ACTION_OT_delete";
1054  ot->description = "Remove all selected keyframes";
1055 
1056  /* api callbacks */
1060 
1061  /* flags */
1064 }
1065 
1066 /* ******************** Clean Keyframes Operator ************************* */
1067 
1068 static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan)
1069 {
1070  ListBase anim_data = {NULL, NULL};
1071  bAnimListElem *ale;
1072  int filter;
1073 
1074  /* filter data */
1076  ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1077  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1078 
1079  /* loop through filtered data and clean curves */
1080  for (ale = anim_data.first; ale; ale = ale->next) {
1081  clean_fcurve(ac, ale, thresh, clean_chan);
1082 
1083  ale->update |= ANIM_UPDATE_DEFAULT;
1084  }
1085 
1086  ANIM_animdata_update(ac, &anim_data);
1087  ANIM_animdata_freelist(&anim_data);
1088 }
1089 
1090 /* ------------------- */
1091 
1093 {
1094  bAnimContext ac;
1095  float thresh;
1096  bool clean_chan;
1097 
1098  /* get editor data */
1099  if (ANIM_animdata_get_context(C, &ac) == 0) {
1100  return OPERATOR_CANCELLED;
1101  }
1102 
1104  BKE_report(op->reports, RPT_ERROR, "Not implemented");
1105  return OPERATOR_PASS_THROUGH;
1106  }
1107 
1108  /* get cleaning threshold */
1109  thresh = RNA_float_get(op->ptr, "threshold");
1110  clean_chan = RNA_boolean_get(op->ptr, "channels");
1111 
1112  /* clean keyframes */
1113  clean_action_keys(&ac, thresh, clean_chan);
1114 
1115  /* set notifier that keyframes have changed */
1117 
1118  return OPERATOR_FINISHED;
1119 }
1120 
1122 {
1123  /* identifiers */
1124  ot->name = "Clean Keyframes";
1125  ot->idname = "ACTION_OT_clean";
1126  ot->description = "Simplify F-Curves by removing closely spaced keyframes";
1127 
1128  /* api callbacks */
1129  // ot->invoke = /* XXX we need that number popup for this! */
1132 
1133  /* flags */
1135 
1136  /* properties */
1137  ot->prop = RNA_def_float(
1138  ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
1139  RNA_def_boolean(ot->srna, "channels", false, "Channels", "");
1140 }
1141 
1142 /* ******************** Sample Keyframes Operator *********************** */
1143 
1144 /* Evaluates the curves between each selected keyframe on each frame, and keys the value */
1146 {
1147  ListBase anim_data = {NULL, NULL};
1148  bAnimListElem *ale;
1149  int filter;
1150 
1151  /* filter data */
1153  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1154  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1155 
1156  /* loop through filtered data and add keys between selected keyframes on every frame */
1157  for (ale = anim_data.first; ale; ale = ale->next) {
1158  sample_fcurve((FCurve *)ale->key_data);
1159 
1160  ale->update |= ANIM_UPDATE_DEPS;
1161  }
1162 
1163  ANIM_animdata_update(ac, &anim_data);
1164  ANIM_animdata_freelist(&anim_data);
1165 }
1166 
1167 /* ------------------- */
1168 
1170 {
1171  bAnimContext ac;
1172 
1173  /* get editor data */
1174  if (ANIM_animdata_get_context(C, &ac) == 0) {
1175  return OPERATOR_CANCELLED;
1176  }
1177 
1179  BKE_report(op->reports, RPT_ERROR, "Not implemented");
1180  return OPERATOR_PASS_THROUGH;
1181  }
1182 
1183  /* sample keyframes */
1184  sample_action_keys(&ac);
1185 
1186  /* set notifier that keyframes have changed */
1188 
1189  return OPERATOR_FINISHED;
1190 }
1191 
1193 {
1194  /* identifiers */
1195  ot->name = "Sample Keyframes";
1196  ot->idname = "ACTION_OT_sample";
1197  ot->description = "Add keyframes on every frame between the selected keyframes";
1198 
1199  /* api callbacks */
1202 
1203  /* flags */
1205 }
1206 
1207 /* ************************************************************************** */
1208 /* SETTINGS STUFF */
1209 
1210 /* ******************** Set Extrapolation-Type Operator *********************** */
1211 
1212 /* defines for make/clear cyclic extrapolation tools */
1213 #define MAKE_CYCLIC_EXPO -1
1214 #define CLEAR_CYCLIC_EXPO -2
1215 
1216 /* defines for set extrapolation-type for selected keyframes tool */
1219  "CONSTANT",
1220  0,
1221  "Constant Extrapolation",
1222  "Values on endpoint keyframes are held"},
1224  "LINEAR",
1225  0,
1226  "Linear Extrapolation",
1227  "Straight-line slope of end segments are extended past the endpoint keyframes"},
1228 
1230  "MAKE_CYCLIC",
1231  0,
1232  "Make Cyclic (F-Modifier)",
1233  "Add Cycles F-Modifier if one doesn't exist already"},
1235  "CLEAR_CYCLIC",
1236  0,
1237  "Clear Cyclic (F-Modifier)",
1238  "Remove Cycles F-Modifier if not needed anymore"},
1239  {0, NULL, 0, NULL, NULL},
1240 };
1241 
1242 /* this function is responsible for setting extrapolation mode for keyframes */
1243 static void setexpo_action_keys(bAnimContext *ac, short mode)
1244 {
1245  ListBase anim_data = {NULL, NULL};
1246  bAnimListElem *ale;
1247  int filter;
1248 
1249  /* filter data */
1251  ANIMFILTER_SEL /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1252  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1253 
1254  /* loop through setting mode per F-Curve */
1255  for (ale = anim_data.first; ale; ale = ale->next) {
1256  FCurve *fcu = (FCurve *)ale->data;
1257 
1258  if (mode >= 0) {
1259  /* just set mode setting */
1260  fcu->extend = mode;
1261  }
1262  else {
1263  /* shortcuts for managing Cycles F-Modifiers to make it easier to toggle cyclic animation
1264  * without having to go through FModifier UI in Graph Editor to do so
1265  */
1266  if (mode == MAKE_CYCLIC_EXPO) {
1267  /* only add if one doesn't exist */
1269  /* TODO: add some more preset versions which set different extrapolation options? */
1271  }
1272  }
1273  else if (mode == CLEAR_CYCLIC_EXPO) {
1274  /* remove all the modifiers fitting this description */
1275  FModifier *fcm, *fcn = NULL;
1276 
1277  for (fcm = fcu->modifiers.first; fcm; fcm = fcn) {
1278  fcn = fcm->next;
1279 
1280  if (fcm->type == FMODIFIER_TYPE_CYCLES) {
1281  remove_fmodifier(&fcu->modifiers, fcm);
1282  }
1283  }
1284  }
1285  }
1286 
1287  ale->update |= ANIM_UPDATE_DEFAULT;
1288  }
1289 
1290  ANIM_animdata_update(ac, &anim_data);
1291  ANIM_animdata_freelist(&anim_data);
1292 }
1293 
1294 /* ------------------- */
1295 
1297 {
1298  bAnimContext ac;
1299  short mode;
1300 
1301  /* get editor data */
1302  if (ANIM_animdata_get_context(C, &ac) == 0) {
1303  return OPERATOR_CANCELLED;
1304  }
1305 
1307  BKE_report(op->reports, RPT_ERROR, "Not implemented");
1308  return OPERATOR_PASS_THROUGH;
1309  }
1310 
1311  /* get handle setting mode */
1312  mode = RNA_enum_get(op->ptr, "type");
1313 
1314  /* set handle type */
1315  setexpo_action_keys(&ac, mode);
1316 
1317  /* set notifier that keyframe properties have changed */
1319 
1320  return OPERATOR_FINISHED;
1321 }
1322 
1324 {
1325  /* identifiers */
1326  ot->name = "Set Keyframe Extrapolation";
1327  ot->idname = "ACTION_OT_extrapolation_type";
1328  ot->description = "Set extrapolation mode for selected F-Curves";
1329 
1330  /* api callbacks */
1334 
1335  /* flags */
1337 
1338  /* id-props */
1339  ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_expo_types, 0, "Type", "");
1340 }
1341 
1342 /* ******************** Set Interpolation-Type Operator *********************** */
1343 
1345 {
1346  bAnimContext ac;
1347  short mode;
1348 
1349  /* get editor data */
1350  if (ANIM_animdata_get_context(C, &ac) == 0) {
1351  return OPERATOR_CANCELLED;
1352  }
1353 
1355  BKE_report(op->reports, RPT_ERROR, "Not implemented");
1356  return OPERATOR_PASS_THROUGH;
1357  }
1358 
1359  /* get handle setting mode */
1360  mode = RNA_enum_get(op->ptr, "type");
1361 
1362  /* set handle type */
1366  ANIM_editkeyframes_ipo(mode));
1367 
1368  /* set notifier that keyframe properties have changed */
1370 
1371  return OPERATOR_FINISHED;
1372 }
1373 
1375 {
1376  /* identifiers */
1377  ot->name = "Set Keyframe Interpolation";
1378  ot->idname = "ACTION_OT_interpolation_type";
1379  ot->description =
1380  "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
1381 
1382  /* api callbacks */
1386 
1387  /* flags */
1389 
1390  /* id-props */
1391  ot->prop = RNA_def_enum(
1392  ot->srna, "type", rna_enum_beztriple_interpolation_mode_items, 0, "Type", "");
1393 }
1394 
1395 /* ******************** Set Easing Operator *********************** */
1396 
1398 {
1399  bAnimContext ac;
1400  short mode;
1401 
1402  /* get editor data */
1403  if (ANIM_animdata_get_context(C, &ac) == 0) {
1404  return OPERATOR_CANCELLED;
1405  }
1406 
1407  /* get handle setting mode */
1408  mode = RNA_enum_get(op->ptr, "type");
1409 
1410  /* set handle type */
1415 
1416  /* set notifier that keyframe properties have changed */
1418 
1419  return OPERATOR_FINISHED;
1420 }
1421 
1423 {
1424  /* identifiers */
1425  ot->name = "Set Keyframe Easing Type";
1426  ot->idname = "ACTION_OT_easing_type";
1427  ot->description =
1428  "Set easing type for the F-Curve segments starting from the selected keyframes";
1429 
1430  /* api callbacks */
1434 
1435  /* flags */
1437 
1438  /* id-props */
1439  ot->prop = RNA_def_enum(
1440  ot->srna, "type", rna_enum_beztriple_interpolation_easing_items, 0, "Type", "");
1441 }
1442 
1443 /* ******************** Set Handle-Type Operator *********************** */
1444 
1445 /* this function is responsible for setting handle-type of selected keyframes */
1446 static void sethandles_action_keys(bAnimContext *ac, short mode)
1447 {
1448  ListBase anim_data = {NULL, NULL};
1449  bAnimListElem *ale;
1450  int filter;
1451 
1454 
1455  /* filter data */
1457  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1458  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1459 
1460  /* Loop through setting flags for handles
1461  * Note: we do not supply KeyframeEditData to the looper yet.
1462  * Currently that's not necessary here.
1463  */
1464  for (ale = anim_data.first; ale; ale = ale->next) {
1465  FCurve *fcu = (FCurve *)ale->key_data;
1466 
1467  /* any selected keyframes for editing? */
1468  if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
1469  /* change type of selected handles */
1471 
1472  ale->update |= ANIM_UPDATE_DEFAULT;
1473  }
1474  }
1475 
1476  ANIM_animdata_update(ac, &anim_data);
1477  ANIM_animdata_freelist(&anim_data);
1478 }
1479 
1480 /* ------------------- */
1481 
1483 {
1484  bAnimContext ac;
1485  short mode;
1486 
1487  /* get editor data */
1488  if (ANIM_animdata_get_context(C, &ac) == 0) {
1489  return OPERATOR_CANCELLED;
1490  }
1491 
1493  BKE_report(op->reports, RPT_ERROR, "Not implemented");
1494  return OPERATOR_PASS_THROUGH;
1495  }
1496 
1497  /* get handle setting mode */
1498  mode = RNA_enum_get(op->ptr, "type");
1499 
1500  /* set handle type */
1501  sethandles_action_keys(&ac, mode);
1502 
1503  /* set notifier that keyframe properties have changed */
1505 
1506  return OPERATOR_FINISHED;
1507 }
1508 
1510 {
1511  /* identifiers */
1512  ot->name = "Set Keyframe Handle Type";
1513  ot->idname = "ACTION_OT_handle_type";
1514  ot->description = "Set type of handle for selected keyframes";
1515 
1516  /* api callbacks */
1520 
1521  /* flags */
1523 
1524  /* id-props */
1525  ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_keyframe_handle_type_items, 0, "Type", "");
1526 }
1527 
1528 /* ******************** Set Keyframe-Type Operator *********************** */
1529 
1530 /* this function is responsible for setting keyframe type for keyframes */
1531 static void setkeytype_action_keys(bAnimContext *ac, short mode)
1532 {
1533  ListBase anim_data = {NULL, NULL};
1534  bAnimListElem *ale;
1535  int filter;
1537 
1538  /* filter data */
1540  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1541  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1542 
1543  /* Loop through setting BezTriple interpolation
1544  * Note: we do not supply KeyframeEditData to the looper yet.
1545  * Currently that's not necessary here.
1546  */
1547  for (ale = anim_data.first; ale; ale = ale->next) {
1549 
1551  }
1552 
1553  ANIM_animdata_update(ac, &anim_data);
1554  ANIM_animdata_freelist(&anim_data);
1555 }
1556 
1557 /* this function is responsible for setting the keyframe type for Grease Pencil frames */
1558 static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
1559 {
1560  ListBase anim_data = {NULL, NULL};
1561  bAnimListElem *ale;
1562  int filter;
1563 
1564  /* filter data */
1567  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1568 
1569  /* loop through each layer */
1570  for (ale = anim_data.first; ale; ale = ale->next) {
1571  if (ale->type == ANIMTYPE_GPLAYER) {
1573  ale->update |= ANIM_UPDATE_DEPS;
1574  }
1575  }
1576 
1577  ANIM_animdata_update(ac, &anim_data);
1578  ANIM_animdata_freelist(&anim_data);
1579 }
1580 
1581 /* ------------------- */
1582 
1584 {
1585  bAnimContext ac;
1586  short mode;
1587 
1588  /* get editor data */
1589  if (ANIM_animdata_get_context(C, &ac) == 0) {
1590  return OPERATOR_CANCELLED;
1591  }
1592 
1593  if (ac.datatype == ANIMCONT_MASK) {
1594  BKE_report(op->reports, RPT_ERROR, "Not implemented for Masks");
1595  return OPERATOR_PASS_THROUGH;
1596  }
1597 
1598  /* get handle setting mode */
1599  mode = RNA_enum_get(op->ptr, "type");
1600 
1601  /* set handle type */
1602  if (ac.datatype == ANIMCONT_GPENCIL) {
1603  setkeytype_gpencil_keys(&ac, mode);
1604  }
1605  else {
1606  setkeytype_action_keys(&ac, mode);
1607  }
1608 
1609  /* set notifier that keyframe properties have changed */
1611 
1612  return OPERATOR_FINISHED;
1613 }
1614 
1616 {
1617  /* identifiers */
1618  ot->name = "Set Keyframe Type";
1619  ot->idname = "ACTION_OT_keyframe_type";
1620  ot->description = "Set type of keyframe for the selected keyframes";
1621 
1622  /* api callbacks */
1626 
1627  /* flags */
1629 
1630  /* id-props */
1631  ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_beztriple_keyframe_type_items, 0, "Type", "");
1632 }
1633 
1634 /* ************************************************************************** */
1635 /* TRANSFORM STUFF */
1636 
1637 /* ***************** Jump to Selected Frames Operator *********************** */
1638 
1640 {
1641  /* prevent changes during render */
1642  if (G.is_rendering) {
1643  return 0;
1644  }
1645 
1646  return ED_operator_action_active(C);
1647 }
1648 
1649 /* snap current-frame indicator to 'average time' of selected keyframe */
1651 {
1652  bAnimContext ac;
1653  ListBase anim_data = {NULL, NULL};
1654  bAnimListElem *ale;
1655  int filter;
1656  KeyframeEditData ked = {{NULL}};
1657 
1658  /* get editor data */
1659  if (ANIM_animdata_get_context(C, &ac) == 0) {
1660  return OPERATOR_CANCELLED;
1661  }
1662 
1663  /* init edit data */
1664  /* loop over action data, averaging values */
1665  filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ |
1667  ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
1668 
1669  for (ale = anim_data.first; ale; ale = ale->next) {
1670  AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
1671  if (adt) {
1672  ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
1674  ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
1675  }
1676  else {
1678  }
1679  }
1680 
1681  ANIM_animdata_freelist(&anim_data);
1682 
1683  /* set the new current frame value, based on the average time */
1684  if (ked.i1) {
1685  Scene *scene = ac.scene;
1686  CFRA = round_fl_to_int(ked.f1 / ked.i1);
1687  SUBFRA = 0.0f;
1688  }
1689 
1690  /* set notifier that things have changed */
1692 
1693  return OPERATOR_FINISHED;
1694 }
1695 
1697 {
1698  /* identifiers */
1699  ot->name = "Jump to Keyframes";
1700  ot->idname = "ACTION_OT_frame_jump";
1701  ot->description = "Set the current frame to the average frame value of selected keyframes";
1702 
1703  /* api callbacks */
1706 
1707  /* flags */
1709 }
1710 
1711 /* ******************** Snap Keyframes Operator *********************** */
1712 
1713 /* defines for snap keyframes tool */
1716  "CFRA",
1717  0,
1718  "Selection to Current Frame",
1719  "Snap selected keyframes to the current frame"},
1721  "NEAREST_FRAME",
1722  0,
1723  "Selection to Nearest Frame",
1724  "Snap selected keyframes to the nearest (whole) frame (use to fix accidental subframe "
1725  "offsets)"},
1727  "NEAREST_SECOND",
1728  0,
1729  "Selection to Nearest Second",
1730  "Snap selected keyframes to the nearest second"},
1732  "NEAREST_MARKER",
1733  0,
1734  "Selection to Nearest Marker",
1735  "Snap selected keyframes to the nearest marker"},
1736  {0, NULL, 0, NULL, NULL},
1737 };
1738 
1739 /* this function is responsible for snapping keyframes to frame-times */
1740 static void snap_action_keys(bAnimContext *ac, short mode)
1741 {
1742  ListBase anim_data = {NULL, NULL};
1743  bAnimListElem *ale;
1744  int filter;
1745 
1746  KeyframeEditData ked = {{NULL}};
1747  KeyframeEditFunc edit_cb;
1748 
1749  /* filter data */
1752  }
1753  else {
1755  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1756  }
1757  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1758 
1759  /* get beztriple editing callbacks */
1760  edit_cb = ANIM_editkeyframes_snap(mode);
1761 
1762  ked.scene = ac->scene;
1763  if (mode == ACTKEYS_SNAP_NEAREST_MARKER) {
1764  ked.list.first = (ac->markers) ? ac->markers->first : NULL;
1765  ked.list.last = (ac->markers) ? ac->markers->last : NULL;
1766  }
1767 
1768  /* snap keyframes */
1769  for (ale = anim_data.first; ale; ale = ale->next) {
1770  AnimData *adt = ANIM_nla_mapping_get(ac, ale);
1771 
1772  if (ale->type == ANIMTYPE_GPLAYER) {
1773  ED_gpencil_layer_snap_frames(ale->data, ac->scene, mode);
1774  }
1775  else if (ale->type == ANIMTYPE_MASKLAYER) {
1776  ED_masklayer_snap_frames(ale->data, ac->scene, mode);
1777  }
1778  else if (adt) {
1779  ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
1781  ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
1782  }
1783  else {
1785  }
1786 
1787  ale->update |= ANIM_UPDATE_DEFAULT;
1788  }
1789 
1790  ANIM_animdata_update(ac, &anim_data);
1791  ANIM_animdata_freelist(&anim_data);
1792 }
1793 
1794 /* ------------------- */
1795 
1797 {
1798  bAnimContext ac;
1799  short mode;
1800 
1801  /* get editor data */
1802  if (ANIM_animdata_get_context(C, &ac) == 0) {
1803  return OPERATOR_CANCELLED;
1804  }
1805 
1806  /* get snapping mode */
1807  mode = RNA_enum_get(op->ptr, "type");
1808 
1809  /* snap keyframes */
1810  snap_action_keys(&ac, mode);
1811 
1812  /* set notifier that keyframes have changed */
1814 
1815  return OPERATOR_FINISHED;
1816 }
1817 
1819 {
1820  /* identifiers */
1821  ot->name = "Snap Keys";
1822  ot->idname = "ACTION_OT_snap";
1823  ot->description = "Snap selected keyframes to the times specified";
1824 
1825  /* api callbacks */
1829 
1830  /* flags */
1832 
1833  /* id-props */
1834  ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_snap_types, 0, "Type", "");
1835 }
1836 
1837 /* ******************** Mirror Keyframes Operator *********************** */
1838 
1839 /* defines for mirror keyframes tool */
1842  "CFRA",
1843  0,
1844  "By Times Over Current Frame",
1845  "Flip times of selected keyframes using the current frame as the mirror line"},
1847  "XAXIS",
1848  0,
1849  "By Values Over Zero Value",
1850  "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"},
1852  "MARKER",
1853  0,
1854  "By Times Over First Selected Marker",
1855  "Flip times of selected keyframes using the first selected marker as the reference point"},
1856  {0, NULL, 0, NULL, NULL},
1857 };
1858 
1859 /* this function is responsible for mirroring keyframes */
1860 static void mirror_action_keys(bAnimContext *ac, short mode)
1861 {
1862  ListBase anim_data = {NULL, NULL};
1863  bAnimListElem *ale;
1864  int filter;
1865 
1866  KeyframeEditData ked = {{NULL}};
1867  KeyframeEditFunc edit_cb;
1868 
1869  /* get beztriple editing callbacks */
1870  edit_cb = ANIM_editkeyframes_mirror(mode);
1871 
1872  ked.scene = ac->scene;
1873 
1874  /* for 'first selected marker' mode, need to find first selected marker first! */
1875  /* XXX should this be made into a helper func in the API? */
1876  if (mode == ACTKEYS_MIRROR_MARKER) {
1878 
1879  if (marker) {
1880  ked.f1 = (float)marker->frame;
1881  }
1882  else {
1883  return;
1884  }
1885  }
1886 
1887  /* filter data */
1891  }
1892  else {
1894  ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS);
1895  }
1896  ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
1897 
1898  /* mirror keyframes */
1899  for (ale = anim_data.first; ale; ale = ale->next) {
1900  AnimData *adt = ANIM_nla_mapping_get(ac, ale);
1901 
1902  if (ale->type == ANIMTYPE_GPLAYER) {
1903  ED_gpencil_layer_mirror_frames(ale->data, ac->scene, mode);
1904  }
1905  else if (ale->type == ANIMTYPE_MASKLAYER) {
1906  /* TODO */
1907  }
1908  else if (adt) {
1909  ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
1911  ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
1912  }
1913  else {
1915  }
1916 
1917  ale->update |= ANIM_UPDATE_DEFAULT;
1918  }
1919 
1920  ANIM_animdata_update(ac, &anim_data);
1921  ANIM_animdata_freelist(&anim_data);
1922 }
1923 
1924 /* ------------------- */
1925 
1927 {
1928  bAnimContext ac;
1929  short mode;
1930 
1931  /* get editor data */
1932  if (ANIM_animdata_get_context(C, &ac) == 0) {
1933  return OPERATOR_CANCELLED;
1934  }
1935 
1936  /* get mirroring mode */
1937  mode = RNA_enum_get(op->ptr, "type");
1938 
1939  /* mirror keyframes */
1940  mirror_action_keys(&ac, mode);
1941 
1942  /* set notifier that keyframes have changed */
1944 
1945  return OPERATOR_FINISHED;
1946 }
1947 
1949 {
1950  /* identifiers */
1951  ot->name = "Mirror Keys";
1952  ot->idname = "ACTION_OT_mirror";
1953  ot->description = "Flip selected keyframes over the selected mirror line";
1954 
1955  /* api callbacks */
1959 
1960  /* flags */
1962 
1963  /* id-props */
1964  ot->prop = RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", "");
1965 }
1966 
1967 /* ************************************************************************** */
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache)
Definition: anim_sys.c:2756
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time)
Definition: anim_sys.c:637
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct SpaceAction * CTX_wm_space_action(const bContext *C)
Definition: context.c:872
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2186
bool BKE_fcurve_calc_range(struct FCurve *fcu, float *min, float *max, const bool do_sel_only, const bool do_min_length)
Definition: fcurve.c:795
bool BKE_fcurve_is_empty(struct FCurve *fcu)
Definition: fcurve.c:2250
bool remove_fmodifier(ListBase *modifiers, struct FModifier *fcm)
Definition: fmodifier.c:1226
void calchandles_fcurve(struct FCurve *fcu)
Definition: fcurve.c:1391
struct FModifier * add_fmodifier(ListBase *modifiers, int type, struct FCurve *owner_fcu)
Definition: fmodifier.c:1114
bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype)
Definition: fmodifier.c:1337
struct bGPDframe * BKE_gpencil_layer_frame_get(struct bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew)
Definition: gpencil.c:1307
void BKE_gpencil_tag(struct bGPdata *gpd)
Definition: gpencil.c:525
eGP_GetFrame_Mode
Definition: BKE_gpencil.h:185
@ GP_GETFRAME_ADD_NEW
Definition: BKE_gpencil.h:190
@ GP_GETFRAME_ADD_COPY
Definition: BKE_gpencil.h:192
@ NLATIME_CONVERT_MAP
Definition: BKE_nla.h:156
@ NLATIME_CONVERT_UNMAP
Definition: BKE_nla.h:153
float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode)
Definition: nla.c:582
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
MINLINE int round_fl_to_int(float a)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:70
#define UNUSED(x)
#define ELEM(...)
@ SACTCONT_ACTION
@ SACTCONT_SHAPEKEY
@ SACTION_POSEMARKERS_SHOW
eInsertKeyFlags
@ FMODIFIER_TYPE_CYCLES
@ FCURVE_EXTRAPOLATE_CONSTANT
@ FCURVE_EXTRAPOLATE_LINEAR
Object is a sort of wrapper for general info.
#define SUBFRA
#define CFRA
#define SCER_PRV_RANGE
@ GP_TOOL_FLAG_RETAIN_LAST
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
#define ACHANNEL_HEIGHT(ac)
Definition: ED_anim_api.h:429
@ ANIMTYPE_NLACURVE
Definition: ED_anim_api.h:210
@ ANIMTYPE_GPLAYER
Definition: ED_anim_api.h:241
@ ANIMTYPE_MASKLAYER
Definition: ED_anim_api.h:244
@ ANIMTYPE_FCURVE
Definition: ED_anim_api.h:207
#define ACHANNEL_FIRST_TOP(ac)
Definition: ED_anim_api.h:427
@ ACHANNEL_ROLE_CHANNEL
Definition: ED_anim_api.h:502
#define ANIM_UPDATE_DEFAULT
Definition: ED_anim_api.h:281
@ ALE_GPFRAME
Definition: ED_anim_api.h:259
@ ALE_MASKLAY
Definition: ED_anim_api.h:260
@ ANIM_UPDATE_DEPS
Definition: ED_anim_api.h:275
@ ANIM_UPDATE_HANDLES
Definition: ED_anim_api.h:277
@ ANIMCONT_MASK
Definition: ED_anim_api.h:125
@ ANIMCONT_GPENCIL
Definition: ED_anim_api.h:119
@ ACHANNEL_SETTING_SELECT
Definition: ED_anim_api.h:519
#define ACHANNEL_STEP(ac)
Definition: ED_anim_api.h:431
@ ANIMFILTER_FOREDIT
Definition: ED_anim_api.h:315
@ ANIMFILTER_DATA_VISIBLE
Definition: ED_anim_api.h:295
@ ANIMFILTER_CURVE_VISIBLE
Definition: ED_anim_api.h:300
@ ANIMFILTER_LIST_VISIBLE
Definition: ED_anim_api.h:298
@ ANIMFILTER_LIST_CHANNELS
Definition: ED_anim_api.h:303
@ ANIMFILTER_NODUPLIS
Definition: ED_anim_api.h:328
@ ANIMFILTER_SEL
Definition: ED_anim_api.h:311
@ ANIMFILTER_ACTGROUPED
Definition: ED_anim_api.h:308
eKeyMergeMode
@ KEYFRAME_PASTE_MERGE_MIX
eKeyPasteOffset
@ KEYFRAME_PASTE_OFFSET_CFRA_START
@ BEZT_OK_SELECTED
short(* KeyframeEditFunc)(KeyframeEditData *ked, struct BezTriple *bezt)
void ED_masklayer_frames_duplicate(struct MaskLayer *mask_layer)
bool ED_masklayer_frames_delete(struct MaskLayer *mask_layer)
void ED_masklayer_snap_frames(struct MaskLayer *mask_layer, struct Scene *scene, short mode)
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
bool ED_operator_action_active(struct bContext *C)
Definition: screen_ops.c:282
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
void UI_view2d_center_set(struct View2D *v2d, float x, float y)
Definition: view2d.c:1950
#define V2D_LOCK_COPY
Definition: UI_view2d.h:84
void UI_view2d_sync(struct bScreen *screen, struct ScrArea *area, struct View2D *v2dcur, int flag)
Definition: view2d.c:876
void UI_view2d_center_get(const struct View2D *v2d, float *r_x, float *r_y)
Definition: view2d.c:1940
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define ND_DATA
Definition: WM_types.h:408
#define NC_ANIMATION
Definition: WM_types.h:289
#define NC_SCENE
Definition: WM_types.h:279
#define NA_ADDED
Definition: WM_types.h:464
#define NA_EDITED
Definition: WM_types.h:462
#define ND_KEYFRAME_PROP
Definition: WM_types.h:395
#define ND_MARKERS
Definition: WM_types.h:333
#define ND_FRAME
Definition: WM_types.h:334
#define NA_REMOVED
Definition: WM_types.h:465
#define NC_GPENCIL
Definition: WM_types.h:300
#define ND_KEYFRAME
Definition: WM_types.h:394
void ACTION_OT_view_selected(wmOperatorType *ot)
Definition: action_edit.c:462
static bool actkeys_framejump_poll(bContext *C)
Definition: action_edit.c:1639
static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:1029
void ACTION_OT_keyframe_type(wmOperatorType *ot)
Definition: action_edit.c:1615
void ACTION_OT_easing_type(wmOperatorType *ot)
Definition: action_edit.c:1422
static void insert_gpencil_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:795
static bool act_markers_make_local_poll(bContext *C)
Definition: action_edit.c:84
static void setkeytype_gpencil_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:1558
static void snap_action_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:1740
static int actkeys_view_frame_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:479
static void clean_action_keys(bAnimContext *ac, float thresh, bool clean_chan)
Definition: action_edit.c:1068
static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:938
static const EnumPropertyItem prop_actkeys_snap_types[]
Definition: action_edit.c:1714
void ACTION_OT_view_all(wmOperatorType *ot)
Definition: action_edit.c:447
void ACTION_OT_sample(wmOperatorType *ot)
Definition: action_edit.c:1192
static int actkeys_viewall(bContext *C, const bool only_sel)
Definition: action_edit.c:363
void ACTION_OT_previewrange_set(wmOperatorType *ot)
Definition: action_edit.c:295
static int actkeys_snap_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1796
void ACTION_OT_duplicate(wmOperatorType *ot)
Definition: action_edit.c:956
void ACTION_OT_delete(wmOperatorType *ot)
Definition: action_edit.c:1049
void ACTION_OT_view_frame(wmOperatorType *ot)
Definition: action_edit.c:487
static int actkeys_previewrange_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:262
void ACTION_OT_extrapolation_type(wmOperatorType *ot)
Definition: action_edit.c:1323
static int actkeys_ipo_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1344
void ACTION_OT_keyframe_insert(wmOperatorType *ot)
Definition: action_edit.c:876
static void insert_action_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:717
static char * actkeys_paste_description(bContext *UNUSED(C), wmOperatorType *UNUSED(op), PointerRNA *ptr)
Definition: action_edit.c:655
static bool delete_action_keys(bAnimContext *ac)
Definition: action_edit.c:973
void ACTION_OT_snap(wmOperatorType *ot)
Definition: action_edit.c:1818
static int act_markers_make_local_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:110
static void duplicate_action_keys(bAnimContext *ac)
Definition: action_edit.c:897
static int actkeys_paste_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:608
#define MAKE_CYCLIC_EXPO
Definition: action_edit.c:1213
void ACTION_OT_frame_jump(wmOperatorType *ot)
Definition: action_edit.c:1696
static void sample_action_keys(bAnimContext *ac)
Definition: action_edit.c:1145
void ACTION_OT_paste(wmOperatorType *ot)
Definition: action_edit.c:668
static int actkeys_clean_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1092
static const EnumPropertyItem prop_actkeys_mirror_types[]
Definition: action_edit.c:1840
static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *r_min, float *r_max)
Definition: action_edit.c:319
static void sethandles_action_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:1446
static void mirror_action_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:1860
void ACTION_OT_copy(wmOperatorType *ot)
Definition: action_edit.c:593
static short copy_action_keys(bAnimContext *ac)
Definition: action_edit.c:508
static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel)
Definition: action_edit.c:167
static int actkeys_easing_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1397
static int actkeys_copy_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:562
static int actkeys_mirror_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1926
void ACTION_OT_markers_make_local(wmOperatorType *ot)
Definition: action_edit.c:146
void ACTION_OT_interpolation_type(wmOperatorType *ot)
Definition: action_edit.c:1374
static int actkeys_expo_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1296
static int actkeys_handletype_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1482
void ACTION_OT_handle_type(wmOperatorType *ot)
Definition: action_edit.c:1509
static const EnumPropertyItem prop_actkeys_insertkey_types[]
Definition: action_edit.c:708
static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:841
void ACTION_OT_mirror(wmOperatorType *ot)
Definition: action_edit.c:1948
static void setexpo_action_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:1243
static void setkeytype_action_keys(bAnimContext *ac, short mode)
Definition: action_edit.c:1531
void ACTION_OT_clean(wmOperatorType *ot)
Definition: action_edit.c:1121
#define CLEAR_CYCLIC_EXPO
Definition: action_edit.c:1214
static int actkeys_viewsel_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:439
static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:1650
static short paste_action_keys(bAnimContext *ac, const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
Definition: action_edit.c:530
static int actkeys_viewall_exec(bContext *C, wmOperator *UNUSED(op))
Definition: action_edit.c:433
static int actkeys_keytype_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1583
static const EnumPropertyItem prop_actkeys_expo_types[]
Definition: action_edit.c:1217
static int actkeys_sample_exec(bContext *C, wmOperator *op)
Definition: action_edit.c:1169
@ ACTKEYS_SNAP_NEAREST_FRAME
@ ACTKEYS_SNAP_NEAREST_SECOND
@ ACTKEYS_SNAP_CFRA
@ ACTKEYS_SNAP_NEAREST_MARKER
@ ACTKEYS_MIRROR_CFRA
@ ACTKEYS_MIRROR_MARKER
@ ACTKEYS_MIRROR_XAXIS
short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
const bAnimChannelType * ANIM_channel_get_typeinfo(bAnimListElem *ale)
void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu)
void ANIM_animdata_freelist(ListBase *anim_data)
Definition: anim_deps.c:425
void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
Definition: anim_deps.c:330
AnimData * ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
Definition: anim_draw.c:178
void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, bool only_keys)
Definition: anim_draw.c:257
void ANIM_center_frame(struct bContext *C, int smooth_viewtx)
Definition: anim_draw.c:588
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
Definition: anim_filter.c:405
size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
Definition: anim_filter.c:3442
TimeMarker * ED_markers_get_first_selected(ListBase *markers)
Definition: anim_markers.c:379
ListBase * ED_context_get_markers(const bContext *C)
Definition: anim_markers.c:103
#define SELECT
Scene scene
void ED_gpencil_layer_frames_keytype_set(bGPDlayer *gpl, short type)
void ED_gpencil_layer_frames_duplicate(bGPDlayer *gpl)
bool ED_gpencil_layer_frames_delete(bGPDlayer *gpl)
bool ED_gpencil_anim_copybuf_paste(bAnimContext *ac, const short offset_mode)
void ED_gpencil_layer_mirror_frames(bGPDlayer *gpl, Scene *scene, short mode)
void ED_gpencil_layer_snap_frames(bGPDlayer *gpl, Scene *scene, short mode)
bool ED_gpencil_anim_copybuf_copy(bAnimContext *ac)
DO_INLINE void filter(lfVector *V, fmatrix3x3 *S)
const vector< Marker > & markers
#define ceilf(x)
#define floorf(x)
#define fabsf(x)
KeyframeEditFunc ANIM_editkeyframes_mirror(short mode)
KeyframeEditFunc ANIM_editkeyframes_keytype(short mode)
KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
KeyframeEditFunc ANIM_editkeyframes_ipo(short mode)
short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
KeyframeEditFunc ANIM_editkeyframes_snap(short mode)
void ANIM_animdata_keyframe_callback(bAnimContext *ac, eAnimFilter_Flags filter, KeyframeEditFunc callback_fn)
short bezt_calc_average(KeyframeEditData *ked, BezTriple *bezt)
KeyframeEditFunc ANIM_editkeyframes_handles(short mode)
void duplicate_fcurve_keys(FCurve *fcu)
const EnumPropertyItem rna_enum_keyframe_paste_offset_items[]
short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data, const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
const EnumPropertyItem rna_enum_keyframe_paste_merge_items[]
void sample_fcurve(FCurve *fcu)
void ANIM_fcurves_copybuf_free(void)
bool delete_fcurve_keys(FCurve *fcu)
void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault)
int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag)
Definition: keyframing.c:547
eInsertKeyFlags ANIM_get_keyframing_flags(Scene *scene, const bool use_autokey_mode)
Definition: keyframing.c:92
int insert_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, const AnimationEvalContext *anim_eval_context, eBezTriple_KeyframeType keytype, ListBase *nla_cache, eInsertKeyFlags flag)
Definition: keyframing.c:1413
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
const EnumPropertyItem rna_enum_beztriple_interpolation_mode_items[]
Definition: rna_curve.c:82
const EnumPropertyItem rna_enum_keyframe_handle_type_items[]
Definition: rna_curve.c:53
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
const EnumPropertyItem rna_enum_beztriple_interpolation_easing_items[]
Definition: rna_fcurve.c:124
const EnumPropertyItem rna_enum_beztriple_keyframe_type_items[]
Definition: rna_fcurve.c:95
#define min(a, b)
Definition: sort.c:51
bActionGroup * grp
char * rna_path
short extend
int array_index
ListBase modifiers
struct FModifier * next
struct Scene * scene
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
struct MaskLayerShape * next
ListBase splines_shapes
struct ToolSettings * toolsettings
struct RenderData r
bAction * action
ListBase markers
bool(* has_setting)(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
Definition: ED_anim_api.h:562
eAnimChannel_Role channel_role
Definition: ED_anim_api.h:541
ListBase * markers
Definition: ED_anim_api.h:105
struct ARegion * region
Definition: ED_anim_api.h:89
struct Scene * scene
Definition: ED_anim_api.h:97
short datatype
Definition: ED_anim_api.h:75
void * data
Definition: ED_anim_api.h:73
struct ReportList * reports
Definition: ED_anim_api.h:108
struct Main * bmain
Definition: ED_anim_api.h:95
struct Depsgraph * depsgraph
Definition: ED_anim_api.h:101
struct bAnimListElem * next
Definition: ED_anim_api.h:135
void * key_data
Definition: ED_anim_api.h:154
struct AnimData * adt
Definition: ED_anim_api.h:170
struct ID * id
Definition: ED_anim_api.h:168
struct bGPDframe * next
ListBase frames
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
char *(* get_description)(struct bContext *C, struct wmOperatorType *, struct PointerRNA *)
Definition: WM_types.h:799
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
struct PointerRNA * ptr
float max
#define G(x, y, z)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_operator_properties_confirm_or_exec(wmOperatorType *ot)
int WM_operator_confirm_or_exec(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
int WM_operator_smooth_viewtx_get(const wmOperator *op)
Definition: wm_operators.c:944
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982