Blender  V3.3
graph_slider_ops.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
14 #include <float.h>
15 #include <string.h>
16 
17 #include "MEM_guardedalloc.h"
18 
19 #include "BLI_listbase.h"
20 #include "BLI_string.h"
21 
22 #include "DNA_anim_types.h"
23 #include "DNA_scene_types.h"
24 
25 #include "RNA_access.h"
26 #include "RNA_define.h"
27 
28 #include "BLT_translation.h"
29 
30 #include "BKE_context.h"
31 
32 #include "UI_interface.h"
33 
34 #include "ED_anim_api.h"
35 #include "ED_keyframes_edit.h"
36 #include "ED_numinput.h"
37 #include "ED_screen.h"
38 #include "ED_util.h"
39 
40 #include "WM_api.h"
41 #include "WM_types.h"
42 
43 #include "graph_intern.h"
44 
45 /* -------------------------------------------------------------------- */
49 /* Used to obtain a list of animation channels for the operators to work on. */
50 #define OPERATOR_DATA_FILTER \
51  (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FCURVESONLY | \
52  ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS)
53 
54 /* This data type is only used for modal operation. */
55 typedef struct tGraphSliderOp {
60 
63 
66 
67  struct tSlider *slider;
68 
69  /* Each operator has a specific update function. */
70  void (*modal_update)(struct bContext *, struct wmOperator *);
71 
74 
75 typedef struct tBeztCopyData {
76  int tot_vert;
79 
82 /* -------------------------------------------------------------------- */
91 {
92  ListBase anim_data = {NULL, NULL};
93  bAnimContext *ac = &gso->ac;
94  bAnimListElem *ale;
95 
96  ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
97 
98  /* Loop through filtered data and copy the curves. */
99  for (ale = anim_data.first; ale; ale = ale->next) {
100  FCurve *fcu = (FCurve *)ale->key_data;
101 
102  if (fcu->bezt == NULL) {
103  /* This curve is baked, skip it. */
104  continue;
105  }
106 
107  const int arr_size = sizeof(BezTriple) * fcu->totvert;
108 
109  tBeztCopyData *copy = MEM_mallocN(sizeof(tBeztCopyData), "bezts_copy");
110  BezTriple *bezts_copy = MEM_mallocN(arr_size, "bezts_copy_array");
111 
112  copy->tot_vert = fcu->totvert;
113  memcpy(bezts_copy, fcu->bezt, arr_size);
114 
115  copy->bezt = bezts_copy;
116 
117  LinkData *link = NULL;
118 
119  link = MEM_callocN(sizeof(LinkData), "Bezt Link");
120  link->data = copy;
121 
122  BLI_addtail(&gso->bezt_arr_list, link);
123  }
124 
125  ANIM_animdata_freelist(&anim_data);
126 }
127 
128 /* Overwrite the current bezts arrays with the original data. */
129 static void reset_bezts(tGraphSliderOp *gso)
130 {
131  ListBase anim_data = {NULL, NULL};
132  LinkData *link_bezt;
133  bAnimListElem *ale;
134 
135  bAnimContext *ac = &gso->ac;
136 
137  /* Filter data. */
138  ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
139 
140  /* Loop through filtered data and reset bezts. */
141  for (ale = anim_data.first, link_bezt = gso->bezt_arr_list.first; ale; ale = ale->next) {
142  FCurve *fcu = (FCurve *)ale->key_data;
143 
144  if (fcu->bezt == NULL) {
145  /* This curve is baked, skip it. */
146  continue;
147  }
148 
149  tBeztCopyData *data = link_bezt->data;
150 
151  const int arr_size = sizeof(BezTriple) * data->tot_vert;
152 
153  MEM_freeN(fcu->bezt);
154 
155  fcu->bezt = MEM_mallocN(arr_size, __func__);
156  fcu->totvert = data->tot_vert;
157 
158  memcpy(fcu->bezt, data->bezt, arr_size);
159 
160  link_bezt = link_bezt->next;
161  }
162 
163  ANIM_animdata_freelist(&anim_data);
164 }
165 
171 {
172  tGraphSliderOp *gso = op->customdata;
173  const float factor = ED_slider_factor_get(gso->slider);
174  RNA_property_float_set(op->ptr, gso->factor_prop, factor);
175  return factor;
176 }
177 
180 /* -------------------------------------------------------------------- */
185 {
186  tGraphSliderOp *gso = op->customdata;
187  wmWindow *win = CTX_wm_window(C);
188 
189  /* If data exists, clear its data and exit. */
190  if (gso == NULL) {
191  return;
192  }
193 
194  ScrArea *area = gso->area;
195  LinkData *link;
196 
197  ED_slider_destroy(C, gso->slider);
198 
199  for (link = gso->bezt_arr_list.first; link != NULL; link = link->next) {
200  tBeztCopyData *copy = link->data;
201  MEM_freeN(copy->bezt);
202  MEM_freeN(link->data);
203  }
204 
206  MEM_freeN(gso);
207 
208  /* Return to normal cursor and header status. */
211 
212  /* cleanup */
213  op->customdata = NULL;
214 }
215 
216 static int graph_slider_modal(bContext *C, wmOperator *op, const wmEvent *event)
217 {
218  tGraphSliderOp *gso = op->customdata;
219 
220  const bool has_numinput = hasNumInput(&gso->num);
221 
222  ED_slider_modal(gso->slider, event);
223 
224  switch (event->type) {
225  /* Confirm */
226  case LEFTMOUSE:
227  case EVT_RETKEY:
228  case EVT_PADENTER: {
229  if (event->val == KM_PRESS) {
230  graph_slider_exit(C, op);
231 
232  return OPERATOR_FINISHED;
233  }
234  break;
235  }
236 
237  /* Cancel */
238  case EVT_ESCKEY:
239  case RIGHTMOUSE: {
240  if (event->val == KM_PRESS) {
241  reset_bezts(gso);
242 
244 
245  graph_slider_exit(C, op);
246 
247  return OPERATOR_CANCELLED;
248  }
249  break;
250  }
251 
252  /* When the mouse is moved, the percentage and the keyframes update. */
253  case MOUSEMOVE: {
254  if (has_numinput == false) {
255  /* Do the update as specified by the operator. */
256  gso->modal_update(C, op);
257  }
258  break;
259  }
260  default: {
261  if ((event->val == KM_PRESS) && handleNumInput(C, &gso->num, event)) {
262  float value;
263  float percentage = RNA_property_float_get(op->ptr, gso->factor_prop);
264 
265  /* Grab percentage from numeric input, and store this new value for redo
266  * NOTE: users see ints, while internally we use a 0-1 float.
267  */
268  value = percentage * 100.0f;
269  applyNumInput(&gso->num, &value);
270 
271  percentage = value / 100.0f;
272  ED_slider_factor_set(gso->slider, percentage);
273  RNA_property_float_set(op->ptr, gso->factor_prop, percentage);
274 
275  gso->modal_update(C, op);
276  break;
277  }
278 
279  /* Unhandled event - maybe it was some view manipulation? */
280  /* Allow to pass through. */
282  }
283  }
284 
285  return OPERATOR_RUNNING_MODAL;
286 }
287 
288 /* Allocate tGraphSliderOp and assign to op->customdata. */
289 static int graph_slider_invoke(bContext *C, wmOperator *op, const wmEvent *event)
290 {
291  tGraphSliderOp *gso;
292 
294 
295  /* Init slide-op data. */
296  gso = op->customdata = MEM_callocN(sizeof(tGraphSliderOp), "tGraphSliderOp");
297 
298  /* Get editor data. */
299  if (ANIM_animdata_get_context(C, &gso->ac) == 0) {
300  graph_slider_exit(C, op);
301  return OPERATOR_CANCELLED;
302  }
303 
304  gso->scene = CTX_data_scene(C);
305  gso->area = CTX_wm_area(C);
306  gso->region = CTX_wm_region(C);
307 
309 
310  gso->slider = ED_slider_create(C);
311  ED_slider_init(gso->slider, event);
312 
313  if (gso->bezt_arr_list.first == NULL) {
314  WM_report(RPT_ERROR, "Cannot find keys to operate on.");
315  graph_slider_exit(C, op);
316  return OPERATOR_CANCELLED;
317  }
318 
320  return OPERATOR_RUNNING_MODAL;
321 }
322 
325 /* -------------------------------------------------------------------- */
329 typedef enum tDecimModes {
333 
334 static void decimate_graph_keys(bAnimContext *ac, float factor, float error_sq_max)
335 {
336  ListBase anim_data = {NULL, NULL};
337  bAnimListElem *ale;
338 
339  /* Filter data. */
340  ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
341 
342  /* Loop through filtered data and clean curves. */
343  for (ale = anim_data.first; ale; ale = ale->next) {
344  if (!decimate_fcurve(ale, factor, error_sq_max)) {
345  /* The selection contains unsupported keyframe types! */
346  WM_report(RPT_WARNING, "Decimate: Skipping non linear/bezier keyframes!");
347  }
348 
349  ale->update |= ANIM_UPDATE_DEFAULT;
350  }
351 
352  ANIM_animdata_update(ac, &anim_data);
353  ANIM_animdata_freelist(&anim_data);
354 }
355 
356 /* Draw a percentage indicator in workspace footer. */
358 {
359  char status_str[UI_MAX_DRAW_STR];
360  char mode_str[32];
361  char slider_string[UI_MAX_DRAW_STR];
362 
363  ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
364 
365  strcpy(mode_str, TIP_("Decimate Keyframes"));
366 
367  if (hasNumInput(&gso->num)) {
368  char str_ofs[NUM_STR_REP_LEN];
369 
370  outputNumInput(&gso->num, str_ofs, &gso->scene->unit);
371 
372  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs);
373  }
374  else {
375  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string);
376  }
377 
378  ED_workspace_status_text(C, status_str);
379 }
380 
382 {
383  /* Perform decimate updates - in response to some user action
384  * (e.g. pressing a key or moving the mouse). */
385  tGraphSliderOp *gso = op->customdata;
386 
387  decimate_draw_status(C, gso);
388 
389  /* Reset keyframe data (so we get back to the original state). */
390  reset_bezts(gso);
391 
392  /* Apply... */
393  const float factor = slider_factor_get_and_remember(op);
394  /* We don't want to limit the decimation to a certain error margin. */
395  const float error_sq_max = FLT_MAX;
396  decimate_graph_keys(&gso->ac, factor, error_sq_max);
398 }
399 
400 static int decimate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
401 {
402  const int invoke_result = graph_slider_invoke(C, op, event);
403 
404  if (invoke_result == OPERATOR_CANCELLED) {
405  return OPERATOR_CANCELLED;
406  }
407 
408  tGraphSliderOp *gso = op->customdata;
409  gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
412 
413  return invoke_result;
414 }
415 
417 {
418  bAnimContext ac;
419 
420  /* Get editor data. */
421  if (ANIM_animdata_get_context(C, &ac) == 0) {
422  return OPERATOR_CANCELLED;
423  }
424 
425  tDecimModes mode = RNA_enum_get(op->ptr, "mode");
426  /* We want to be able to work on all available keyframes. */
427  float factor = 1.0f;
428  /* We don't want to limit the decimation to a certain error margin. */
429  float error_sq_max = FLT_MAX;
430 
431  switch (mode) {
432  case DECIM_RATIO:
433  factor = RNA_float_get(op->ptr, "factor");
434  break;
435  case DECIM_ERROR:
436  error_sq_max = RNA_float_get(op->ptr, "remove_error_margin");
437  /* The decimate algorithm expects the error to be squared. */
438  error_sq_max *= error_sq_max;
439 
440  break;
441  }
442 
443  if (factor == 0.0f || error_sq_max == 0.0f) {
444  /* Nothing to remove. */
445  return OPERATOR_FINISHED;
446  }
447 
448  decimate_graph_keys(&ac, factor, error_sq_max);
449 
450  /* Set notifier that keyframes have changed. */
452 
453  return OPERATOR_FINISHED;
454 }
455 
457  wmOperator *op,
458  const PropertyRNA *prop)
459 {
460  const char *prop_id = RNA_property_identifier(prop);
461 
462  if (STRPREFIX(prop_id, "remove")) {
463  int mode = RNA_enum_get(op->ptr, "mode");
464 
465  if (STREQ(prop_id, "factor") && mode != DECIM_RATIO) {
466  return false;
467  }
468  if (STREQ(prop_id, "remove_error_margin") && mode != DECIM_ERROR) {
469  return false;
470  }
471  }
472 
473  return true;
474 }
475 
477 {
478 
479  if (RNA_enum_get(ptr, "mode") == DECIM_ERROR) {
480  return BLI_strdup(
481  TIP_("Decimate F-Curves by specifying how much they can deviate from the original curve"));
482  }
483 
484  /* Use default description. */
485  return NULL;
486 }
487 
489  {DECIM_RATIO,
490  "RATIO",
491  0,
492  "Ratio",
493  "Use a percentage to specify how many keyframes you want to remove"},
494  {DECIM_ERROR,
495  "ERROR",
496  0,
497  "Error Margin",
498  "Use an error margin to specify how much the curve is allowed to deviate from the original "
499  "path"},
500  {0, NULL, 0, NULL, NULL},
501 };
502 
504 {
505  /* Identifiers */
506  ot->name = "Decimate Keyframes";
507  ot->idname = "GRAPH_OT_decimate";
508  ot->description =
509  "Decimate F-Curves by removing keyframes that influence the curve shape the least";
510 
511  /* API callbacks */
516  ot->exec = decimate_exec;
518 
519  /* Flags */
521 
522  /* Properties */
524  "mode",
526  DECIM_RATIO,
527  "Mode",
528  "Which mode to use for decimation");
529 
531  "factor",
532  1.0f / 3.0f,
533  0.0f,
534  1.0f,
535  "Remove",
536  "The ratio of remaining keyframes after the operation",
537  0.0f,
538  1.0f);
540  "remove_error_margin",
541  0.0f,
542  0.0f,
543  FLT_MAX,
544  "Max Error Margin",
545  "How much the new decimated curve is allowed to deviate from the original",
546  0.0f,
547  10.0f);
548 }
549 
552 /* -------------------------------------------------------------------- */
556 static void blend_to_neighbor_graph_keys(bAnimContext *ac, float factor)
557 {
558  ListBase anim_data = {NULL, NULL};
559  ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
560 
561  bAnimListElem *ale;
562 
563  /* Loop through filtered data and blend keys. */
564 
565  for (ale = anim_data.first; ale; ale = ale->next) {
566  FCurve *fcu = (FCurve *)ale->key_data;
567  ListBase segments = find_fcurve_segments(fcu);
568  LISTBASE_FOREACH (FCurveSegment *, segment, &segments) {
570  }
571  BLI_freelistN(&segments);
572  ale->update |= ANIM_UPDATE_DEFAULT;
573  }
574 
575  ANIM_animdata_update(ac, &anim_data);
576  ANIM_animdata_freelist(&anim_data);
577 }
578 
580 {
581  char status_str[UI_MAX_DRAW_STR];
582  char mode_str[32];
583  char slider_string[UI_MAX_DRAW_STR];
584 
585  ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
586 
587  strcpy(mode_str, TIP_("Blend to Neighbor"));
588 
589  if (hasNumInput(&gso->num)) {
590  char str_ofs[NUM_STR_REP_LEN];
591 
592  outputNumInput(&gso->num, str_ofs, &gso->scene->unit);
593 
594  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs);
595  }
596  else {
597  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string);
598  }
599 
600  ED_workspace_status_text(C, status_str);
601 }
602 
604 {
605  tGraphSliderOp *gso = op->customdata;
606 
608 
609  /* Reset keyframe data to the state at invoke. */
610  reset_bezts(gso);
611 
612  const float factor = slider_factor_get_and_remember(op);
613  blend_to_neighbor_graph_keys(&gso->ac, factor);
614 
616 }
617 
618 static int blend_to_neighbor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
619 {
620  const int invoke_result = graph_slider_invoke(C, op, event);
621 
622  if (invoke_result == OPERATOR_CANCELLED) {
623  return invoke_result;
624  }
625 
626  tGraphSliderOp *gso = op->customdata;
628  gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
630 
631  return invoke_result;
632 }
633 
635 {
636  bAnimContext ac;
637 
638  if (ANIM_animdata_get_context(C, &ac) == 0) {
639  return OPERATOR_CANCELLED;
640  }
641 
642  const float factor = RNA_float_get(op->ptr, "factor");
643 
644  blend_to_neighbor_graph_keys(&ac, factor);
645 
646  /* Set notifier that keyframes have changed. */
648 
649  return OPERATOR_FINISHED;
650 }
651 
653 {
654  /* Identifiers. */
655  ot->name = "Blend to Neighbor";
656  ot->idname = "GRAPH_OT_blend_to_neighbor";
657  ot->description = "Blend selected keyframes to their left or right neighbor";
658 
659  /* API callbacks. */
664 
665  /* Flags. */
667 
669  "factor",
670  1.0f / 3.0f,
671  -FLT_MAX,
672  FLT_MAX,
673  "Blend",
674  "The blend factor with 0.5 being the current frame",
675  0.0f,
676  1.0f);
677 }
678 
681 /* -------------------------------------------------------------------- */
685 static void breakdown_graph_keys(bAnimContext *ac, float factor)
686 {
687  ListBase anim_data = {NULL, NULL};
688  ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
689 
690  bAnimListElem *ale;
691 
692  for (ale = anim_data.first; ale; ale = ale->next) {
693  FCurve *fcu = (FCurve *)ale->key_data;
694  ListBase segments = find_fcurve_segments(fcu);
695  LISTBASE_FOREACH (FCurveSegment *, segment, &segments) {
696  breakdown_fcurve_segment(fcu, segment, factor);
697  }
698  BLI_freelistN(&segments);
699  ale->update |= ANIM_UPDATE_DEFAULT;
700  }
701 
702  ANIM_animdata_update(ac, &anim_data);
703  ANIM_animdata_freelist(&anim_data);
704 }
705 
707 {
708  char status_str[UI_MAX_DRAW_STR];
709  char mode_str[32];
710  char slider_string[UI_MAX_DRAW_STR];
711 
712  ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
713 
714  strcpy(mode_str, TIP_("Breakdown"));
715 
716  if (hasNumInput(&gso->num)) {
717  char str_ofs[NUM_STR_REP_LEN];
718 
719  outputNumInput(&gso->num, str_ofs, &gso->scene->unit);
720 
721  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs);
722  }
723  else {
724  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string);
725  }
726 
727  ED_workspace_status_text(C, status_str);
728 }
729 
731 {
732  tGraphSliderOp *gso = op->customdata;
733 
735 
736  /* Reset keyframe data to the state at invoke. */
737  reset_bezts(gso);
738  const float factor = slider_factor_get_and_remember(op);
739  breakdown_graph_keys(&gso->ac, factor);
741 }
742 
743 static int breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
744 {
745  const int invoke_result = graph_slider_invoke(C, op, event);
746 
747  if (invoke_result == OPERATOR_CANCELLED) {
748  return invoke_result;
749  }
750 
751  tGraphSliderOp *gso = op->customdata;
753  gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
755 
756  return invoke_result;
757 }
758 
760 {
761  bAnimContext ac;
762 
763  if (ANIM_animdata_get_context(C, &ac) == 0) {
764  return OPERATOR_CANCELLED;
765  }
766 
767  const float factor = RNA_float_get(op->ptr, "factor");
768 
769  breakdown_graph_keys(&ac, factor);
770 
771  /* Set notifier that keyframes have changed. */
773 
774  return OPERATOR_FINISHED;
775 }
776 
778 {
779  /* Identifiers. */
780  ot->name = "Breakdown";
781  ot->idname = "GRAPH_OT_breakdown";
782  ot->description = "Move selected keyframes to an inbetween position relative to adjacent keys";
783 
784  /* API callbacks. */
789 
790  /* Flags. */
792 
794  "factor",
795  1.0f / 3.0f,
796  -FLT_MAX,
797  FLT_MAX,
798  "Factor",
799  "Favor either the left or the right key",
800  0.0f,
801  1.0f);
802 }
803 
806 /* -------------------------------------------------------------------- */
810 static void blend_to_default_graph_keys(bAnimContext *ac, const float factor)
811 {
812  ListBase anim_data = {NULL, NULL};
813  ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype);
814 
815  LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
816  FCurve *fcu = (FCurve *)ale->key_data;
817 
818  /* Check if the curves actually have any points. */
819  if (fcu == NULL || fcu->bezt == NULL || fcu->totvert == 0) {
820  continue;
821  }
822 
823  PointerRNA id_ptr;
824  RNA_id_pointer_create(ale->id, &id_ptr);
825 
826  blend_to_default_fcurve(&id_ptr, fcu, factor);
827  ale->update |= ANIM_UPDATE_DEFAULT;
828  }
829 
830  ANIM_animdata_update(ac, &anim_data);
831  ANIM_animdata_freelist(&anim_data);
832 }
833 
835 {
836  char status_str[UI_MAX_DRAW_STR];
837  char mode_str[32];
838  char slider_string[UI_MAX_DRAW_STR];
839 
840  ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
841 
842  strcpy(mode_str, TIP_("Blend to Default Value"));
843 
844  if (hasNumInput(&gso->num)) {
845  char str_ofs[NUM_STR_REP_LEN];
846 
847  outputNumInput(&gso->num, str_ofs, &gso->scene->unit);
848 
849  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs);
850  }
851  else {
852  BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string);
853  }
854 
855  ED_workspace_status_text(C, status_str);
856 }
857 
859 {
860  tGraphSliderOp *gso = op->customdata;
861 
863 
864  /* Set notifier that keyframes have changed. */
865  reset_bezts(gso);
866  const float factor = ED_slider_factor_get(gso->slider);
867  RNA_property_float_set(op->ptr, gso->factor_prop, factor);
868  blend_to_default_graph_keys(&gso->ac, factor);
870 }
871 
872 static int blend_to_default_invoke(bContext *C, wmOperator *op, const wmEvent *event)
873 {
874  const int invoke_result = graph_slider_invoke(C, op, event);
875 
876  if (invoke_result == OPERATOR_CANCELLED) {
877  return invoke_result;
878  }
879 
880  tGraphSliderOp *gso = op->customdata;
882  gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
884 
885  return invoke_result;
886 }
887 
889 {
890  bAnimContext ac;
891 
892  if (ANIM_animdata_get_context(C, &ac) == 0) {
893  return OPERATOR_CANCELLED;
894  }
895 
896  const float factor = RNA_float_get(op->ptr, "factor");
897 
898  blend_to_default_graph_keys(&ac, factor);
899 
900  /* Set notifier that keyframes have changed. */
902 
903  return OPERATOR_FINISHED;
904 }
905 
907 {
908  /* Identifiers. */
909  ot->name = "Blend to Default Value";
910  ot->idname = "GRAPH_OT_blend_to_default";
911  ot->description = "Blend selected keys to their default value from their current position";
912 
913  /* API callbacks. */
918 
919  /* Flags. */
921 
923  "factor",
924  1.0f / 3.0f,
925  -FLT_MAX,
926  FLT_MAX,
927  "Factor",
928  "How much to blend to the default value",
929  0.0f,
930  1.0f);
931 }
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STRPREFIX(a, b)
#define UNUSED(x)
#define STREQ(a, b)
#define TIP_(msgid)
struct BezTriple BezTriple
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
#define ANIM_UPDATE_DEFAULT
Definition: ED_anim_api.h:274
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:87
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:13
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:189
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event)
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:816
void ED_slider_init(struct tSlider *slider, const struct wmEvent *event)
void ED_slider_allow_overshoot_set(struct tSlider *slider, bool value)
Definition: ed_draw.c:498
void ED_slider_status_string_get(const struct tSlider *slider, char *status_string, size_t size_of_status_string)
Definition: ed_draw.c:424
float ED_slider_factor_get(struct tSlider *slider)
Definition: ed_draw.c:480
bool ED_slider_modal(struct tSlider *slider, const struct wmEvent *event)
void ED_slider_factor_set(struct tSlider *slider, float factor)
Definition: ed_draw.c:485
void ED_slider_destroy(struct bContext *C, struct tSlider *slider)
Definition: ed_draw.c:467
struct tSlider * ED_slider_create(struct bContext *C)
Definition: ed_draw.c:358
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
@ KM_PRESS
Definition: WM_types.h:267
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define NC_ANIMATION
Definition: WM_types.h:338
#define NA_EDITED
Definition: WM_types.h:523
#define ND_KEYFRAME
Definition: WM_types.h:442
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
SyclQueue void void size_t num_bytes void
bool graphop_editable_keyframes_poll(struct bContext *C)
Definition: graph_utils.c:163
struct tGraphSliderOp tGraphSliderOp
static int blend_to_neighbor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void breakdown_draw_status_header(bContext *C, tGraphSliderOp *gso)
static int decimate_exec(bContext *C, wmOperator *op)
static int blend_to_default_exec(bContext *C, wmOperator *op)
static void reset_bezts(tGraphSliderOp *gso)
void GRAPH_OT_blend_to_neighbor(wmOperatorType *ot)
static const EnumPropertyItem decimate_mode_items[]
static int breakdown_exec(bContext *C, wmOperator *op)
static void blend_to_neighbor_graph_keys(bAnimContext *ac, float factor)
static void blend_to_default_modal_update(bContext *C, wmOperator *op)
static int graph_slider_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int decimate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
tDecimModes
@ DECIM_RATIO
@ DECIM_ERROR
static int blend_to_default_invoke(bContext *C, wmOperator *op, const wmEvent *event)
#define OPERATOR_DATA_FILTER
static char * decimate_desc(bContext *UNUSED(C), wmOperatorType *UNUSED(op), PointerRNA *ptr)
static void blend_to_default_draw_status_header(bContext *C, tGraphSliderOp *gso)
static bool decimate_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
static void decimate_modal_update(bContext *C, wmOperator *op)
void GRAPH_OT_breakdown(wmOperatorType *ot)
static float slider_factor_get_and_remember(wmOperator *op)
static void blend_to_default_graph_keys(bAnimContext *ac, const float factor)
static void breakdown_modal_update(bContext *C, wmOperator *op)
static void blend_to_neighbor_modal_update(bContext *C, wmOperator *op)
static int blend_to_neighbor_exec(bContext *C, wmOperator *op)
static void decimate_graph_keys(bAnimContext *ac, float factor, float error_sq_max)
static int graph_slider_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void GRAPH_OT_decimate(wmOperatorType *ot)
static void breakdown_graph_keys(bAnimContext *ac, float factor)
static void blend_to_neighbor_draw_status_header(bContext *C, tGraphSliderOp *gso)
static int breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void GRAPH_OT_blend_to_default(wmOperatorType *ot)
static void graph_slider_exit(bContext *C, wmOperator *op)
static void store_original_bezt_arrays(tGraphSliderOp *gso)
static void decimate_draw_status(bContext *C, tGraphSliderOp *gso)
struct tBeztCopyData tBeztCopyData
bool decimate_fcurve(bAnimListElem *ale, float remove_ratio, float error_sq_max)
void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor)
void blend_to_default_fcurve(PointerRNA *id_ptr, FCurve *fcu, const float factor)
ListBase find_fcurve_segments(FCurve *fcu)
void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
Segment< FEdge *, Vec3r > segment
static void area(int d1, int d2, int e1, int e2, float weights[2])
static void copy(bNodeTree *dest_ntree, bNode *dest_node, const bNode *src_node)
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2767
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:112
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
Definition: rna_access.c:2790
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
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:3836
PropertyRNA * RNA_def_float_factor(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:4144
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:3783
BezTriple * bezt
unsigned int totvert
void * data
Definition: DNA_listBase.h:26
struct LinkData * next
Definition: DNA_listBase.h:25
void * first
Definition: DNA_listBase.h:31
struct UnitSettings unit
short datatype
Definition: ED_anim_api.h:62
void * data
Definition: ED_anim_api.h:60
struct bAnimListElem * next
Definition: ED_anim_api.h:127
void * key_data
Definition: ED_anim_api.h:146
BezTriple * bezt
bAnimContext ac
void(* modal_update)(struct bContext *, struct wmOperator *)
PropertyRNA * factor_prop
ListBase bezt_arr_list
struct tSlider * slider
short val
Definition: WM_types.h:680
short type
Definition: WM_types.h:678
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
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
char *(* get_description)(struct bContext *C, struct wmOperatorType *, struct PointerRNA *)
Definition: WM_types.h:966
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:949
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
struct PointerRNA * ptr
void WM_cursor_modal_set(wmWindow *win, int val)
Definition: wm_cursors.c:191
void WM_cursor_modal_restore(wmWindow *win)
Definition: wm_cursors.c:200
@ WM_CURSOR_EW_SCROLL
Definition: wm_cursors.h:53
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_report(eReportType type, const char *message)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_PADENTER
@ MOUSEMOVE
@ LEFTMOUSE
@ EVT_ESCKEY
@ EVT_RETKEY
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479