Blender  V2.93
anim_ops.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) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <stdlib.h>
26 
27 #include "BLI_sys_types.h"
28 
29 #include "BLI_math_base.h"
30 #include "BLI_utildefines.h"
31 
32 #include "DNA_scene_types.h"
33 
34 #include "BKE_context.h"
35 #include "BKE_global.h"
36 #include "BKE_report.h"
37 #include "BKE_scene.h"
38 
39 #include "UI_view2d.h"
40 
41 #include "RNA_access.h"
42 #include "RNA_define.h"
43 
44 #include "WM_api.h"
45 #include "WM_types.h"
46 
47 #include "ED_anim_api.h"
48 #include "ED_screen.h"
49 #include "ED_sequencer.h"
50 #include "ED_time_scrub_ui.h"
51 
52 #include "DEG_depsgraph.h"
53 
54 #include "SEQ_sequencer.h"
55 #include "SEQ_time.h"
56 
57 #include "anim_intern.h"
58 
59 /* ********************** frame change operator ***************************/
60 
61 /* Check if the operator can be run from the current context */
63 {
65 
66  /* XXX temp? prevent changes during render */
67  if (G.is_rendering) {
68  return false;
69  }
70 
71  /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
72  * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
73  */
74  if (area) {
76  return true;
77  }
78  }
79 
80  CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
81  return false;
82 }
83 
84 /* Set the new frame number */
86 {
88  float frame = RNA_float_get(op->ptr, "frame");
89  bool do_snap = RNA_boolean_get(op->ptr, "snap");
90 
91  if (do_snap) {
92  if (CTX_wm_space_seq(C)) {
93  frame = SEQ_time_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
94  }
95  else {
96  frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame);
97  }
98  }
99 
100  /* set the new frame number */
101  if (scene->r.flag & SCER_SHOW_SUBFRAME) {
102  CFRA = (int)frame;
103  SUBFRA = frame - (int)frame;
104  }
105  else {
106  CFRA = round_fl_to_int(frame);
107  SUBFRA = 0.0f;
108  }
110 
111  /* do updates */
114 }
115 
116 /* ---- */
117 
118 /* Non-modal callback for running operator without user input */
120 {
121  change_frame_apply(C, op);
122 
123  return OPERATOR_FINISHED;
124 }
125 
126 /* ---- */
127 
128 /* Get frame from mouse coordinates */
129 static float frame_from_event(bContext *C, const wmEvent *event)
130 {
131  ARegion *region = CTX_wm_region(C);
133  float frame;
134 
135  /* convert from region coordinates to View2D 'tot' space */
136  frame = UI_view2d_region_to_view_x(&region->v2d, event->mval[0]);
137 
138  /* respect preview range restrictions (if only allowed to move around within that range) */
140  CLAMP(frame, PSFRA, PEFRA);
141  }
142 
143  return frame;
144 }
145 
147 {
149  bScreen *screen = CTX_wm_screen(C);
150  if (area && area->spacetype == SPACE_SEQ) {
151  SpaceSeq *sseq = area->spacedata.first;
152  ARegion *region = CTX_wm_region(C);
154  !ED_time_scrub_event_in_region(region, event)) {
156  }
157  }
158  if (screen) {
159  screen->scrubbing = true;
160  }
161 }
162 
164 {
165  bScreen *screen = CTX_wm_screen(C);
166  bool notify = false;
167 
168  if (screen->scrubbing) {
169  screen->scrubbing = false;
170  notify = true;
171  }
172 
175  notify = true;
176  }
177 
178  if (notify) {
181  }
182 }
183 
184 /* Modal Operator init */
185 static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
186 {
187  /* Change to frame that mouse is over before adding modal handler,
188  * as user could click on a single frame (jump to frame) as well as
189  * click-dragging over a range (modal scrubbing).
190  */
191  RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
192 
194 
195  change_frame_apply(C, op);
196 
197  /* add temp handler */
199 
200  return OPERATOR_RUNNING_MODAL;
201 }
202 
204 {
206 }
207 
208 /* Modal event handling of frame changing */
209 static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
210 {
212  /* execute the events */
213  switch (event->type) {
214  case EVT_ESCKEY:
216  break;
217 
218  case MOUSEMOVE:
219  RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
220  change_frame_apply(C, op);
221  break;
222 
223  case LEFTMOUSE:
224  case RIGHTMOUSE:
225  case MIDDLEMOUSE:
226  /* We check for either mouse-button to end, to work with all user keymaps. */
227  if (event->val == KM_RELEASE) {
229  }
230  break;
231 
232  case EVT_LEFTCTRLKEY:
233  case EVT_RIGHTCTRLKEY:
234  if (event->val == KM_RELEASE) {
235  RNA_boolean_set(op->ptr, "snap", false);
236  }
237  else if (event->val == KM_PRESS) {
238  RNA_boolean_set(op->ptr, "snap", true);
239  }
240  break;
241  }
242 
243  if (ret != OPERATOR_RUNNING_MODAL) {
245  }
246 
247  return ret;
248 }
249 
251 {
252  PropertyRNA *prop;
253 
254  /* identifiers */
255  ot->name = "Change Frame";
256  ot->idname = "ANIM_OT_change_frame";
257  ot->description = "Interactively change the current frame number";
258 
259  /* api callbacks */
265 
266  /* flags */
268  ot->undo_group = "Frame Change";
269 
270  /* rna */
271  ot->prop = RNA_def_float(
272  ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
273  prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", "");
275 }
276 
277 /* ****************** Start/End Frame Operators *******************************/
278 
280 {
282 
283  /* XXX temp? prevent changes during render */
284  if (G.is_rendering) {
285  return false;
286  }
287 
288  /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
289  * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
290  */
291  if (area) {
293  return true;
294  }
295  }
296 
297  CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
298  return false;
299 }
300 
302 {
304  int frame;
305 
306  if (scene == NULL) {
307  return OPERATOR_CANCELLED;
308  }
309 
310  frame = CFRA;
311 
312  /* if Preview Range is defined, set the 'start' frame for that */
313  if (PRVRANGEON) {
314  scene->r.psfra = frame;
315  }
316  else {
317  /* Clamping should be in sync with 'rna_Scene_start_frame_set()'. */
318  int frame_clamped = frame;
319  CLAMP(frame_clamped, MINFRAME, MAXFRAME);
320  if (frame_clamped != frame) {
321  BKE_report(op->reports, RPT_WARNING, "Start frame clamped to valid rendering range");
322  }
323  frame = frame_clamped;
324  scene->r.sfra = frame;
325  }
326 
327  if (PEFRA < frame) {
328  if (PRVRANGEON) {
329  scene->r.pefra = frame;
330  }
331  else {
332  scene->r.efra = frame;
333  }
334  }
335 
337 
338  return OPERATOR_FINISHED;
339 }
340 
342 {
343  /* identifiers */
344  ot->name = "Set Start Frame";
345  ot->idname = "ANIM_OT_start_frame_set";
346  ot->description = "Set the current frame as the preview or scene start frame";
347 
348  /* api callbacks */
351 
352  /* flags */
354 }
355 
357 {
359  int frame;
360 
361  if (scene == NULL) {
362  return OPERATOR_CANCELLED;
363  }
364 
365  frame = CFRA;
366 
367  /* if Preview Range is defined, set the 'end' frame for that */
368  if (PRVRANGEON) {
369  scene->r.pefra = frame;
370  }
371  else {
372  /* Clamping should be in sync with 'rna_Scene_end_frame_set()'. */
373  int frame_clamped = frame;
374  CLAMP(frame_clamped, MINFRAME, MAXFRAME);
375  if (frame_clamped != frame) {
376  BKE_report(op->reports, RPT_WARNING, "End frame clamped to valid rendering range");
377  }
378  frame = frame_clamped;
379  scene->r.efra = frame;
380  }
381 
382  if (PSFRA > frame) {
383  if (PRVRANGEON) {
384  scene->r.psfra = frame;
385  }
386  else {
387  scene->r.sfra = frame;
388  }
389  }
390 
392 
393  return OPERATOR_FINISHED;
394 }
395 
397 {
398  /* identifiers */
399  ot->name = "Set End Frame";
400  ot->idname = "ANIM_OT_end_frame_set";
401  ot->description = "Set the current frame as the preview or scene end frame";
402 
403  /* api callbacks */
406 
407  /* flags */
409 }
410 
411 /* ****************** set preview range operator ****************************/
412 
414 {
416  ARegion *region = CTX_wm_region(C);
417  float sfra, efra;
418  rcti rect;
419 
420  /* get min/max values from box select rect (already in region coordinates, not screen) */
422 
423  /* convert min/max values to frames (i.e. region to 'tot' rect) */
424  sfra = UI_view2d_region_to_view_x(&region->v2d, rect.xmin);
425  efra = UI_view2d_region_to_view_x(&region->v2d, rect.xmax);
426 
427  /* set start/end frames for preview-range
428  * - must clamp within allowable limits
429  * - end must not be before start (though this won't occur most of the time)
430  */
431  FRAMENUMBER_MIN_CLAMP(sfra);
432  FRAMENUMBER_MIN_CLAMP(efra);
433  if (efra < sfra) {
434  efra = sfra;
435  }
436 
438  scene->r.psfra = round_fl_to_int(sfra);
439  scene->r.pefra = round_fl_to_int(efra);
440 
441  /* send notifiers */
443 
444  return OPERATOR_FINISHED;
445 }
446 
448 {
449  /* identifiers */
450  ot->name = "Set Preview Range";
451  ot->idname = "ANIM_OT_previewrange_set";
452  ot->description = "Interactively define frame range used for playback";
453 
454  /* api callbacks */
459 
461 
462  /* flags */
464 
465  /* rna */
466  /* used to define frame range.
467  *
468  * note: border Y values are not used,
469  * but are needed by box_select gesture operator stuff */
471 }
472 
473 /* ****************** clear preview range operator ****************************/
474 
476 {
478  ScrArea *curarea = CTX_wm_area(C);
479 
480  /* sanity checks */
481  if (ELEM(NULL, scene, curarea)) {
482  return OPERATOR_CANCELLED;
483  }
484 
485  /* simply clear values */
486  scene->r.flag &= ~SCER_PRV_RANGE;
487  scene->r.psfra = 0;
488  scene->r.pefra = 0;
489 
490  ED_area_tag_redraw(curarea);
491 
492  /* send notifiers */
494 
495  return OPERATOR_FINISHED;
496 }
497 
499 {
500  /* identifiers */
501  ot->name = "Clear Preview Range";
502  ot->idname = "ANIM_OT_previewrange_clear";
503  ot->description = "Clear preview range";
504 
505  /* api callbacks */
507 
509 
510  /* flags */
512 }
513 
514 /* ************************** registration **********************************/
515 
517 {
518  /* Animation Editors only -------------------------- */
520 
523 
526 
527  /* Entire UI --------------------------------------- */
538 
544 
547 
552 
554 }
555 
557 {
558  WM_keymap_ensure(keyconf, "Animation", 0, 0);
559 }
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct SpaceSeq * CTX_wm_space_seq(const bContext *C)
Definition: context.c:827
struct bScreen * CTX_wm_screen(const bContext *C)
Definition: context.c:709
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg)
Definition: context.c:1006
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
int BKE_scene_frame_snap_by_seconds(struct Scene *scene, double interval_in_seconds, int cfra)
Definition: scene.c:2407
MINLINE int round_fl_to_int(float a)
#define UNUSED(x)
#define ELEM(...)
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_AUDIO_SEEK
Definition: DNA_ID.h:660
#define SCER_LOCK_FRAME_SELECTION
#define SUBFRA
#define MINFRAME
#define MINAFRAME
#define CFRA
#define PSFRA
#define SCER_PRV_RANGE
#define SCER_SHOW_SUBFRAME
#define PRVRANGEON
#define PEFRA
#define MAXFRAME
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_GRAPH
#define FRAMENUMBER_MIN_CLAMP(cfra)
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:745
bool ED_operator_animview_active(struct bContext *C)
Definition: screen_ops.c:246
Sequence * ED_sequencer_special_preview_get(void)
bool ED_space_sequencer_check_show_strip(struct SpaceSeq *sseq)
void ED_sequencer_special_preview_set(struct bContext *C, const int mval[2])
void ED_sequencer_special_preview_clear(void)
Group RGB to Bright Vector Camera CLAMP
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
#define C
Definition: RandGen.cpp:39
@ SEQ_SIDE_BOTH
Definition: SEQ_sequencer.h:43
float UI_view2d_region_to_view_x(const struct View2D *v2d, float x)
Definition: view2d.c:1659
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
@ OPTYPE_UNDO_GROUPED
Definition: WM_types.h:180
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
@ OPTYPE_GRAB_CURSOR_X
Definition: WM_types.h:163
#define NC_SCENE
Definition: WM_types.h:279
#define KM_PRESS
Definition: WM_types.h:242
#define ND_FRAME
Definition: WM_types.h:334
#define KM_RELEASE
Definition: WM_types.h:243
void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot)
Definition: keyframing.c:2691
void ANIM_OT_keyframe_delete_by_name(struct wmOperatorType *ot)
Definition: keyframing.c:2185
void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot)
Definition: keyframing.c:2582
void ANIM_OT_keying_set_add(struct wmOperatorType *ot)
Definition: keyingsets.c:133
void ANIM_OT_paste_driver_button(struct wmOperatorType *ot)
Definition: drivers.c:1310
void ANIM_OT_copy_driver_button(struct wmOperatorType *ot)
Definition: drivers.c:1260
void ANIM_OT_driver_button_remove(struct wmOperatorType *ot)
Definition: drivers.c:1178
void ANIM_OT_keyingset_button_remove(struct wmOperatorType *ot)
Definition: keyingsets.c:453
void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot)
Definition: keyframing.c:2287
void ANIM_OT_keyingset_button_add(struct wmOperatorType *ot)
Definition: keyingsets.c:371
void ANIM_OT_keying_set_path_remove(struct wmOperatorType *ot)
Definition: keyingsets.c:267
void ANIM_OT_keyframe_insert(struct wmOperatorType *ot)
Definition: keyframing.c:1935
void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot)
Definition: keyframing.c:2758
void ANIM_OT_driver_button_edit(struct wmOperatorType *ot)
Definition: drivers.c:1215
void ANIM_OT_driver_button_add(struct wmOperatorType *ot)
Definition: drivers.c:1125
void ANIM_OT_keying_set_path_add(struct wmOperatorType *ot)
Definition: keyingsets.c:224
void ANIM_OT_keying_set_active_set(struct wmOperatorType *ot)
Definition: keyingsets.c:502
void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot)
Definition: keyframing.c:2411
void ANIM_OT_keyframe_delete(struct wmOperatorType *ot)
Definition: keyframing.c:2151
void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot)
Definition: keyframing.c:2033
void ANIM_OT_keying_set_remove(struct wmOperatorType *ot)
Definition: keyingsets.c:181
void ANIM_OT_keyframe_insert_by_name(struct wmOperatorType *ot)
Definition: keyframing.c:1971
static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: anim_ops.c:185
static void ANIM_OT_previewrange_set(wmOperatorType *ot)
Definition: anim_ops.c:447
static bool anim_set_end_frames_poll(bContext *C)
Definition: anim_ops.c:279
static void ANIM_OT_previewrange_clear(wmOperatorType *ot)
Definition: anim_ops.c:498
static int previewrange_clear_exec(bContext *C, wmOperator *UNUSED(op))
Definition: anim_ops.c:475
static int anim_set_sfra_exec(bContext *C, wmOperator *op)
Definition: anim_ops.c:301
static void ANIM_OT_start_frame_set(wmOperatorType *ot)
Definition: anim_ops.c:341
static int change_frame_exec(bContext *C, wmOperator *op)
Definition: anim_ops.c:119
static int anim_set_efra_exec(bContext *C, wmOperator *op)
Definition: anim_ops.c:356
static void ANIM_OT_end_frame_set(wmOperatorType *ot)
Definition: anim_ops.c:396
static void change_frame_cancel(bContext *C, wmOperator *UNUSED(op))
Definition: anim_ops.c:203
static int previewrange_define_exec(bContext *C, wmOperator *op)
Definition: anim_ops.c:413
static float frame_from_event(bContext *C, const wmEvent *event)
Definition: anim_ops.c:129
void ED_operatortypes_anim(void)
Definition: anim_ops.c:516
static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: anim_ops.c:209
void ED_keymap_anim(wmKeyConfig *keyconf)
Definition: anim_ops.c:556
static bool change_frame_poll(bContext *C)
Definition: anim_ops.c:62
static void ANIM_OT_change_frame(wmOperatorType *ot)
Definition: anim_ops.c:250
static void change_frame_seq_preview_end(bContext *C)
Definition: anim_ops.c:163
static void change_frame_apply(bContext *C, wmOperator *op)
Definition: anim_ops.c:85
static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event)
Definition: anim_ops.c:146
Scene scene
static void area(int d1, int d2, int e1, int e2, float weights[2])
return ret
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:6366
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
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
int SEQ_time_find_next_prev_edit(Scene *scene, int timeline_frame, const short side, const bool do_skip_mute, const bool do_center, const bool do_unselected)
Definition: strip_time.c:270
struct RenderData r
char scrubbing
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
short val
Definition: WM_types.h:579
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
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
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
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
const char * undo_group
Definition: WM_types.h:728
struct ReportList * reports
struct PointerRNA * ptr
bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
#define G(x, y, z)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_RIGHTCTRLKEY
@ EVT_LEFTCTRLKEY
@ MOUSEMOVE
@ LEFTMOUSE
@ MIDDLEMOUSE
@ EVT_ESCKEY
wmOperatorType * ot
Definition: wm_files.c:3156
void WM_gesture_box_cancel(bContext *C, wmOperator *op)
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:852
void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
void WM_operator_properties_border(wmOperatorType *ot)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))