Blender V4.3
anim_ops.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <cmath>
10#include <cstdlib>
11
12#include "BLI_sys_types.h"
13
14#include "BLI_math_base.h"
15#include "BLI_utildefines.h"
16#include "BLI_vector.hh"
17
18#include "DNA_scene_types.h"
19
20#include "BKE_anim_data.hh"
21#include "BKE_context.hh"
22#include "BKE_global.hh"
23#include "BKE_lib_id.hh"
24#include "BKE_lib_query.hh"
25#include "BKE_report.hh"
26#include "BKE_scene.hh"
27
28#include "UI_view2d.hh"
29
30#include "RNA_access.hh"
31#include "RNA_define.hh"
32
33#include "WM_api.hh"
34#include "WM_types.hh"
35
36#include "ED_anim_api.hh"
37#include "ED_screen.hh"
38#include "ED_sequencer.hh"
39#include "ED_time_scrub_ui.hh"
40
41#include "DEG_depsgraph.hh"
43
44#include "SEQ_iterator.hh"
45#include "SEQ_sequencer.hh"
46#include "SEQ_time.hh"
47
48#include "ANIM_action.hh"
49#include "ANIM_animdata.hh"
50
51#include "anim_intern.hh"
52
53/* -------------------------------------------------------------------- */
57/* Check if the operator can be run from the current context */
59{
60 ScrArea *area = CTX_wm_area(C);
61
62 /* XXX temp? prevent changes during render */
63 if (G.is_rendering) {
64 return false;
65 }
66
67 /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
68 * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
69 */
70 if (area) {
71 if (ELEM(area->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_CLIP)) {
72 return true;
73 }
74 if (area->spacetype == SPACE_SEQ) {
75 /* Check the region type so tools (which are shared between preview/strip view)
76 * don't conflict with actions which can have the same key bound (2D cursor for example). */
77 const ARegion *region = CTX_wm_region(C);
78 if (region && region->regiontype == RGN_TYPE_WINDOW) {
79 return true;
80 }
81 }
82 if (area->spacetype == SPACE_GRAPH) {
83 const SpaceGraph *sipo = static_cast<const SpaceGraph *>(area->spacedata.first);
84 /* Driver Editor's X axis is not time. */
85 if (sipo->mode != SIPO_MODE_DRIVERS) {
86 return true;
87 }
88 }
89 }
90
91 CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
92 return false;
93}
94
96{
97 const int snap_distance = SEQ_tool_settings_snap_distance_get(CTX_data_scene(C));
98 const ARegion *region = CTX_wm_region(C);
99 return round_fl_to_int(UI_view2d_region_to_view_x(&region->v2d, snap_distance) -
100 UI_view2d_region_to_view_x(&region->v2d, 0));
101}
102
103static void seq_frame_snap_update_best(const int position,
104 const int timeline_frame,
105 int *r_best_frame,
106 int *r_best_distance)
107{
108 if (abs(position - timeline_frame) < *r_best_distance) {
109 *r_best_distance = abs(position - timeline_frame);
110 *r_best_frame = position;
111 }
112}
113
114static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame)
115{
116
118
119 int best_frame = 0;
120 int best_distance = MAXFRAME;
121 for (Sequence *seq : SEQ_query_all_strips(seqbase)) {
123 SEQ_time_left_handle_frame_get(scene, seq), timeline_frame, &best_frame, &best_distance);
125 SEQ_time_right_handle_frame_get(scene, seq), timeline_frame, &best_frame, &best_distance);
126 }
127
128 if (best_distance < seq_snap_threshold_get_frame_distance(C)) {
129 return best_frame;
130 }
131
132 return timeline_frame;
133}
134
135/* Set the new frame number */
136static void change_frame_apply(bContext *C, wmOperator *op, const bool always_update)
137{
138 Scene *scene = CTX_data_scene(C);
139 float frame = RNA_float_get(op->ptr, "frame");
140 bool do_snap = RNA_boolean_get(op->ptr, "snap");
141
142 const int old_frame = scene->r.cfra;
143 const float old_subframe = scene->r.subframe;
144
145 if (do_snap) {
146 if (CTX_wm_space_seq(C) && SEQ_editing_get(scene) != nullptr) {
147 frame = seq_frame_apply_snap(C, scene, frame);
148 }
149 else {
150 frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame);
151 }
152 }
153
154 /* set the new frame number */
155 if (scene->r.flag & SCER_SHOW_SUBFRAME) {
156 scene->r.cfra = int(frame);
157 scene->r.subframe = frame - int(frame);
158 }
159 else {
160 scene->r.cfra = round_fl_to_int(frame);
161 scene->r.subframe = 0.0f;
162 }
163 FRAMENUMBER_MIN_CLAMP(scene->r.cfra);
164
165 /* do updates */
166 const bool frame_changed = (old_frame != scene->r.cfra) || (old_subframe != scene->r.subframe);
167 if (frame_changed || always_update) {
170 }
171}
172
173/* ---- */
174
175/* Non-modal callback for running operator without user input */
177{
178 change_frame_apply(C, op, true);
179
180 return OPERATOR_FINISHED;
181}
182
183/* ---- */
184
185/* Get frame from mouse coordinates */
186static float frame_from_event(bContext *C, const wmEvent *event)
187{
188 ARegion *region = CTX_wm_region(C);
189 Scene *scene = CTX_data_scene(C);
190 float frame;
191
192 /* convert from region coordinates to View2D 'tot' space */
193 frame = UI_view2d_region_to_view_x(&region->v2d, event->mval[0]);
194
195 /* respect preview range restrictions (if only allowed to move around within that range) */
196 if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
197 CLAMP(frame, PSFRA, PEFRA);
198 }
199
200 return frame;
201}
202
203static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event, SpaceSeq *sseq)
204{
205 BLI_assert(sseq != nullptr);
206 ARegion *region = CTX_wm_region(C);
209 }
210}
211
213{
214 BLI_assert(sseq != nullptr);
215 UNUSED_VARS_NDEBUG(sseq);
216 if (ED_sequencer_special_preview_get() != nullptr) {
218 }
219}
220
222{
223 if (!CTX_wm_space_seq(C)) {
224 return false;
225 }
226
227 Scene *scene = CTX_data_scene(C);
228 short snap_flag = SEQ_tool_settings_snap_flag_get(scene);
229 return (scene->toolsettings->snap_flag_seq & SCE_SNAP) &&
231}
232
233static bool sequencer_skip_for_handle_tweak(const bContext *C, const wmEvent *event)
234{
235 if ((U.sequencer_editor_flag & USER_SEQ_ED_SIMPLE_TWEAKING) == 0) {
236 return false;
237 }
238
239 const Scene *scene = CTX_data_scene(C);
240 if (!SEQ_editing_get(scene)) {
241 return false;
242 }
243
244 const View2D *v2d = UI_view2d_fromcontext(C);
245
246 float mouse_co[2];
247 UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouse_co[0], &mouse_co[1]);
248
249 StripSelection selection = ED_sequencer_pick_strip_and_handle(scene, v2d, mouse_co);
250
251 return selection.handle != SEQ_HANDLE_NONE;
252}
253
254/* Modal Operator init */
255static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
256{
257 ARegion *region = CTX_wm_region(C);
258 bScreen *screen = CTX_wm_screen(C);
259 if (CTX_wm_space_seq(C) != nullptr && region->regiontype == RGN_TYPE_PREVIEW) {
260 return OPERATOR_CANCELLED;
261 }
262 if (sequencer_skip_for_handle_tweak(C, event)) {
264 }
265
266 /* Change to frame that mouse is over before adding modal handler,
267 * as user could click on a single frame (jump to frame) as well as
268 * click-dragging over a range (modal scrubbing).
269 */
270 RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
271
272 if (use_sequencer_snapping(C)) {
273 RNA_boolean_set(op->ptr, "snap", true);
274 }
275
276 screen->scrubbing = true;
277 SpaceSeq *sseq = CTX_wm_space_seq(C);
278 if (sseq) {
279 change_frame_seq_preview_begin(C, event, sseq);
280 }
281
282 change_frame_apply(C, op, true);
283
284 /* add temp handler */
286
288}
289
291{
292 if (CTX_wm_space_seq(C)) {
293 /* During scrubbing in the sequencer, a preview of the final video might be drawn. After
294 * scrubbing, the actual result should be shown again. */
295 return true;
296 }
297 Scene *scene = CTX_data_scene(C);
298 if (scene->eevee.taa_samples != 1) {
299 return true;
300 }
302 Object *object = CTX_data_active_object(C);
303 if (object && object->type == OB_GPENCIL_LEGACY) {
304 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
306 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
307 SpaceLink *sl = (SpaceLink *)area->spacedata.first;
308 if (sl->spacetype == SPACE_VIEW3D) {
309 View3D *v3d = (View3D *)sl;
310 if ((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) {
311 if (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) {
312 /* Grease pencil onion skin is not drawn during scrubbing. Redraw is necessary after
313 * scrubbing ends to show onion skin again. */
314 return true;
315 }
316 }
317 }
318 }
319 }
320 }
321 return false;
322}
323
324static void change_frame_cancel(bContext *C, wmOperator * /*op*/)
325{
326 bScreen *screen = CTX_wm_screen(C);
327 screen->scrubbing = false;
328
329 SpaceSeq *sseq = CTX_wm_space_seq(C);
330 if (sseq != nullptr) {
332 }
333
335 Scene *scene = CTX_data_scene(C);
337 }
338}
339
340/* Modal event handling of frame changing */
341static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
342{
344 /* execute the events */
345 switch (event->type) {
346 case EVT_ESCKEY:
348 break;
349
350 case MOUSEMOVE:
351 RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
352 change_frame_apply(C, op, false);
353 break;
354
355 case LEFTMOUSE:
356 case RIGHTMOUSE:
357 case MIDDLEMOUSE:
358 /* We check for either mouse-button to end, to work with all user keymaps. */
359 if (event->val == KM_RELEASE) {
361 }
362 break;
363
364 case EVT_LEFTCTRLKEY:
365 case EVT_RIGHTCTRLKEY:
366 /* Use Ctrl key to invert snapping in sequencer. */
367 if (use_sequencer_snapping(C)) {
368 if (event->val == KM_RELEASE) {
369 RNA_boolean_set(op->ptr, "snap", true);
370 }
371 else if (event->val == KM_PRESS) {
372 RNA_boolean_set(op->ptr, "snap", false);
373 }
374 }
375 else {
376 if (event->val == KM_RELEASE) {
377 RNA_boolean_set(op->ptr, "snap", false);
378 }
379 else if (event->val == KM_PRESS) {
380 RNA_boolean_set(op->ptr, "snap", true);
381 }
382 }
383 break;
384 }
385
387 bScreen *screen = CTX_wm_screen(C);
388 screen->scrubbing = false;
389
390 SpaceSeq *sseq = CTX_wm_space_seq(C);
391 if (sseq != nullptr) {
393 }
395 Scene *scene = CTX_data_scene(C);
397 }
398 }
399
400 return ret;
401}
402
404{
405 PropertyRNA *prop;
406
407 /* identifiers */
408 ot->name = "Change Frame";
409 ot->idname = "ANIM_OT_change_frame";
410 ot->description = "Interactively change the current frame number";
411
412 /* api callbacks */
418
419 /* flags */
421 ot->undo_group = "Frame Change";
422
423 /* rna */
425 ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
426 prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", "");
428}
429
432/* -------------------------------------------------------------------- */
437{
438 ScrArea *area = CTX_wm_area(C);
439
440 /* XXX temp? prevent changes during render */
441 if (G.is_rendering) {
442 return false;
443 }
444
445 /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
446 * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
447 */
448 if (area) {
449 if (ELEM(area->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
450 return true;
451 }
452 }
453
454 CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
455 return false;
456}
457
459{
460 Scene *scene = CTX_data_scene(C);
461 int frame;
462
463 if (scene == nullptr) {
464 return OPERATOR_CANCELLED;
465 }
466
467 frame = scene->r.cfra;
468
469 /* if Preview Range is defined, set the 'start' frame for that */
470 if (PRVRANGEON) {
471 scene->r.psfra = frame;
472 }
473 else {
474 /* Clamping should be in sync with 'rna_Scene_start_frame_set()'. */
475 int frame_clamped = frame;
476 CLAMP(frame_clamped, MINFRAME, MAXFRAME);
477 if (frame_clamped != frame) {
478 BKE_report(op->reports, RPT_WARNING, "Start frame clamped to valid rendering range");
479 }
480 frame = frame_clamped;
481 scene->r.sfra = frame;
482 }
483
484 if (PEFRA < frame) {
485 if (PRVRANGEON) {
486 scene->r.pefra = frame;
487 }
488 else {
489 scene->r.efra = frame;
490 }
491 }
492
494
495 return OPERATOR_FINISHED;
496}
497
499{
500 /* identifiers */
501 ot->name = "Set Start Frame";
502 ot->idname = "ANIM_OT_start_frame_set";
503 ot->description = "Set the current frame as the preview or scene start frame";
504
505 /* api callbacks */
508
509 /* flags */
511}
512
514{
515 Scene *scene = CTX_data_scene(C);
516 int frame;
517
518 if (scene == nullptr) {
519 return OPERATOR_CANCELLED;
520 }
521
522 frame = scene->r.cfra;
523
524 /* if Preview Range is defined, set the 'end' frame for that */
525 if (PRVRANGEON) {
526 scene->r.pefra = frame;
527 }
528 else {
529 /* Clamping should be in sync with 'rna_Scene_end_frame_set()'. */
530 int frame_clamped = frame;
531 CLAMP(frame_clamped, MINFRAME, MAXFRAME);
532 if (frame_clamped != frame) {
533 BKE_report(op->reports, RPT_WARNING, "End frame clamped to valid rendering range");
534 }
535 frame = frame_clamped;
536 scene->r.efra = frame;
537 }
538
539 if (PSFRA > frame) {
540 if (PRVRANGEON) {
541 scene->r.psfra = frame;
542 }
543 else {
544 scene->r.sfra = frame;
545 }
546 }
547
549
550 return OPERATOR_FINISHED;
551}
552
554{
555 /* identifiers */
556 ot->name = "Set End Frame";
557 ot->idname = "ANIM_OT_end_frame_set";
558 ot->description = "Set the current frame as the preview or scene end frame";
559
560 /* api callbacks */
563
564 /* flags */
566}
567
570/* -------------------------------------------------------------------- */
575{
576 Scene *scene = CTX_data_scene(C);
577 ARegion *region = CTX_wm_region(C);
578 float sfra, efra;
579 rcti rect;
580
581 /* get min/max values from box select rect (already in region coordinates, not screen) */
583
584 /* convert min/max values to frames (i.e. region to 'tot' rect) */
585 sfra = UI_view2d_region_to_view_x(&region->v2d, rect.xmin);
586 efra = UI_view2d_region_to_view_x(&region->v2d, rect.xmax);
587
588 /* set start/end frames for preview-range
589 * - must clamp within allowable limits
590 * - end must not be before start (though this won't occur most of the time)
591 */
594 if (efra < sfra) {
595 efra = sfra;
596 }
597
598 scene->r.flag |= SCER_PRV_RANGE;
599 scene->r.psfra = round_fl_to_int(sfra);
600 scene->r.pefra = round_fl_to_int(efra);
601
602 /* send notifiers */
604
605 return OPERATOR_FINISHED;
606}
607
609{
610 /* identifiers */
611 ot->name = "Set Preview Range";
612 ot->idname = "ANIM_OT_previewrange_set";
613 ot->description = "Interactively define frame range used for playback";
614
615 /* api callbacks */
620
622
623 /* flags */
625
626 /* rna */
627 /* used to define frame range.
628 *
629 * NOTE: border Y values are not used,
630 * but are needed by box_select gesture operator stuff */
632}
633
636/* -------------------------------------------------------------------- */
641{
642 Scene *scene = CTX_data_scene(C);
643 ScrArea *curarea = CTX_wm_area(C);
644
645 /* sanity checks */
646 if (ELEM(nullptr, scene, curarea)) {
647 return OPERATOR_CANCELLED;
648 }
649
650 /* simply clear values */
651 scene->r.flag &= ~SCER_PRV_RANGE;
652 scene->r.psfra = 0;
653 scene->r.pefra = 0;
654
655 ED_area_tag_redraw(curarea);
656
657 /* send notifiers */
659
660 return OPERATOR_FINISHED;
661}
662
664{
665 /* identifiers */
666 ot->name = "Clear Preview Range";
667 ot->idname = "ANIM_OT_previewrange_clear";
668 ot->description = "Clear preview range";
669
670 /* api callbacks */
672
674
675 /* flags */
677}
678
681/* -------------------------------------------------------------------- */
686{
687 ARegion *region = CTX_wm_region(C);
688 const Scene *scene = CTX_data_scene(C);
689 BLI_assert(region);
690 BLI_assert(scene);
691
692 View2D &v2d = region->v2d;
693 v2d.cur.xmin = PSFRA;
694 v2d.cur.xmax = PEFRA;
695
697
700
701 return OPERATOR_FINISHED;
702}
703
705{
706 ot->name = "Frame Scene/Preview Range";
707 ot->idname = "ANIM_OT_scene_range_frame";
708 ot->description =
709 "Reset the horizontal view to the current scene frame range, taking the preview range into "
710 "account if it is active";
711
714
716}
717
720/* -------------------------------------------------------------------- */
725{
726 using namespace blender;
727
728 Object *object = CTX_data_active_object(C);
729 if (!object) {
730 return false;
731 }
732 animrig::Action *action = animrig::get_action(object->id);
733 if (!action) {
735 C, "Creating a new Action Slot is only possible when an Action is already assigned");
736 return false;
737 }
738 return action->is_action_layered();
739}
740
742{
743 using namespace blender::animrig;
744
745 Object *object = CTX_data_active_object(C);
746 Action *action = get_action(object->id);
747 BLI_assert_msg(action, "The poll function should have ensured the Action is not NULL");
748
749 Slot &slot = action->slot_add_for_id(object->id);
750 { /* Assign the newly created slot. */
751 const ActionSlotAssignmentResult result = assign_action_slot(&slot, object->id);
752 BLI_assert_msg(result == ActionSlotAssignmentResult::OK,
753 "Assigning a slot that was made for this ID should always work");
754 UNUSED_VARS_NDEBUG(result);
755 }
756
759 return OPERATOR_FINISHED;
760}
761
763{
764 /* identifiers */
765 ot->name = "New Slot";
766 ot->idname = "ANIM_OT_slot_new_for_object";
767 ot->description = "Create a new Slot for this object, on the Action already assigned to it";
768
769 /* api callbacks */
772
773 /* flags */
775}
776
778{
779 using namespace blender;
780
781 Object *object = CTX_data_active_object(C);
782 AnimData *adt = BKE_animdata_from_id(&object->id);
783 BLI_assert(adt != nullptr);
784 BLI_assert(adt->action != nullptr);
785
786 animrig::Action &legacy_action = adt->action->wrap();
787 Main *bmain = CTX_data_main(C);
788
789 animrig::Action *layered_action = animrig::convert_to_layered_action(*bmain, legacy_action);
790 /* We did already check if the action can be converted. */
791 BLI_assert(layered_action != nullptr);
792 const bool assign_ok = animrig::assign_action(layered_action, object->id);
793 BLI_assert_msg(assign_ok, "Expecting assigning a layered Action to always work");
794 UNUSED_VARS_NDEBUG(assign_ok);
795
796 BLI_assert(layered_action->slots().size() == 1);
797 animrig::Slot *slot = layered_action->slot(0);
798 layered_action->slot_name_set(*bmain, *slot, object->id.name);
799
800 const animrig::ActionSlotAssignmentResult result = animrig::assign_action_slot(slot, object->id);
801 BLI_assert(result == animrig::ActionSlotAssignmentResult::OK);
802 UNUSED_VARS_NDEBUG(result);
803
804 ANIM_id_update(bmain, &object->id);
807
808 return OPERATOR_FINISHED;
809}
810
812{
813 Object *object = CTX_data_active_object(C);
814 if (!object) {
815 return false;
816 }
817
818 AnimData *adt = BKE_animdata_from_id(&object->id);
819 if (!adt || !adt->action) {
820 return false;
821 }
822
823 /* This will also convert empty actions to layered by just adding an empty slot. */
824 if (!adt->action->wrap().is_action_legacy()) {
825 CTX_wm_operator_poll_msg_set(C, "Action is already layered");
826 return false;
827 }
828
829 return true;
830}
831
833{
834 /* identifiers */
835 ot->name = "Convert Legacy Action";
836 ot->idname = "ANIM_OT_convert_legacy_action";
837 ot->description = "Convert a legacy Action to a layered Action on the active object";
838
839 /* api callbacks */
842
843 /* flags */
845}
846
848{
849 Object *object = CTX_data_active_object(C);
850 if (!object) {
851 CTX_wm_operator_poll_msg_set(C, "No active object");
852 return false;
853 }
855 if (!action) {
856 CTX_wm_operator_poll_msg_set(C, "Active object has no action");
857 return false;
858 }
859 if (!BKE_id_is_editable(CTX_data_main(C), &action->id)) {
860 return false;
861 }
862 return true;
863}
864
866{
867 using namespace blender::animrig;
868 Object *active_object = CTX_data_active_object(C);
869 /* Those cases are caught by the poll. */
870 BLI_assert(active_object != nullptr);
871 BLI_assert(active_object->adt->action != nullptr);
872
873 Action &active_action = active_object->adt->action->wrap();
874
876 if (!CTX_data_selected_objects(C, &selection)) {
877 return OPERATOR_CANCELLED;
878 }
879
880 Main *bmain = CTX_data_main(C);
881 for (const PointerRNA &ptr : selection) {
882 blender::Vector<ID *> related_ids = find_related_ids(*bmain, *ptr.owner_id);
883 for (ID *related_id : related_ids) {
884 Action *action = get_action(*related_id);
885 if (!action) {
886 continue;
887 }
888 if (action == &active_action) {
889 /* Object is already animated by the same action, no point in moving. */
890 continue;
891 }
892 if (action->is_action_legacy()) {
893 continue;
894 }
895 if (!BKE_id_is_editable(bmain, &action->id)) {
896 BKE_reportf(op->reports, RPT_WARNING, "The action %s is not editable", action->id.name);
897 continue;
898 }
899 AnimData *id_anim_data = BKE_animdata_ensure_id(related_id);
900 /* Since we already get an action from the ID the animdata has to exist. */
901 BLI_assert(id_anim_data);
902 Slot *slot = action->slot_for_handle(id_anim_data->slot_handle);
903 if (!slot) {
904 continue;
905 }
906 blender::animrig::move_slot(*bmain, *slot, *action, active_action);
907 ANIM_id_update(bmain, related_id);
908 }
909 }
910
913
914 return OPERATOR_FINISHED;
915}
916
918{
919 ot->name = "Merge Animation";
920 ot->idname = "ANIM_OT_merge_animation";
921 ot->description =
922 "Merge the animation of the selected objects into the action of the active object. Actions "
923 "are not deleted by this, but might end up with zero users";
924
927
929}
930
933/* -------------------------------------------------------------------- */
938{
939 /* Animation Editors only -------------------------- */
941
944
947
949
950 /* Entire UI --------------------------------------- */
961
967
970
975
977
981}
982
984{
985 WM_keymap_ensure(keyconf, "Animation", SPACE_EMPTY, RGN_TYPE_WINDOW);
986}
987
Functions and classes to work with Actions.
Functions to work with AnimData.
AnimData * BKE_animdata_ensure_id(ID *id)
Definition anim_data.cc:103
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:89
bScreen * CTX_wm_screen(const bContext *C)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
ScrArea * CTX_wm_area(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
SpaceSeq * CTX_wm_space_seq(const bContext *C)
bool CTX_data_selected_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2456
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
Definition scene.cc:2273
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define LISTBASE_FOREACH(type, var, list)
MINLINE int round_fl_to_int(float a)
#define CLAMP(a, b, c)
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_FRAME_CHANGE
Definition DNA_ID.h:1092
@ OB_GPENCIL_LEGACY
#define MINFRAME
@ SCER_SHOW_SUBFRAME
@ SCER_PRV_RANGE
@ SCER_LOCK_FRAME_SELECTION
#define MINAFRAME
@ SEQ_SNAP_CURRENT_FRAME_TO_STRIPS
#define PSFRA
@ SCE_SNAP
#define PRVRANGEON
#define PEFRA
#define MAXFRAME
@ RGN_TYPE_WINDOW
@ RGN_TYPE_PREVIEW
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_EMPTY
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ SIPO_MODE_DRIVERS
#define FRAMENUMBER_MIN_CLAMP(cfra)
@ USER_SEQ_ED_SIMPLE_TWEAKING
@ V3D_GP_SHOW_ONION_SKIN
@ V3D_HIDE_OVERLAYS
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_area_tag_redraw(ScrArea *area)
Definition area.cc:708
bool ED_operator_animview_active(bContext *C)
bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
StripSelection ED_sequencer_pick_strip_and_handle(const struct Scene *scene, const View2D *v2d, float mouse_co[2])
Sequence * ED_sequencer_special_preview_get()
void ED_sequencer_special_preview_clear()
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
@ SEQ_HANDLE_NONE
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag)
Definition view2d.cc:861
#define V2D_LOCK_COPY
Definition UI_view2d.hh:85
View2D * UI_view2d_fromcontext(const bContext *C)
Definition view2d.cc:1850
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
Definition view2d.cc:1663
float UI_view2d_region_to_view_x(const View2D *v2d, float x)
Definition view2d.cc:1652
@ OPTYPE_BLOCKING
Definition WM_types.hh:164
@ OPTYPE_UNDO_GROUPED
Definition WM_types.hh:187
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
@ OPTYPE_GRAB_CURSOR_X
Definition WM_types.hh:170
#define ND_NLA_ACTCHANGE
Definition WM_types.hh:465
#define NC_ANIMATION
Definition WM_types.hh:355
@ KM_PRESS
Definition WM_types.hh:284
@ KM_RELEASE
Definition WM_types.hh:285
#define NC_SCENE
Definition WM_types.hh:345
#define ND_FRAME
Definition WM_types.hh:401
#define ND_ANIMCHAN
Definition WM_types.hh:463
void ANIM_id_update(Main *bmain, ID *id)
Definition anim_deps.cc:102
rctf ANIM_frame_range_view2d_add_xmargin(const View2D &view_2d, const rctf view_rect)
Definition anim_draw.cc:706
void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
void ANIM_OT_keying_set_add(wmOperatorType *ot)
void ANIM_OT_driver_button_remove(wmOperatorType *ot)
Definition drivers.cc:1108
void ANIM_OT_driver_button_add(wmOperatorType *ot)
Definition drivers.cc:1060
void ANIM_OT_keyframe_insert(wmOperatorType *ot)
void ANIM_OT_driver_button_edit(wmOperatorType *ot)
Definition drivers.cc:1144
void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
void ANIM_OT_keyframe_insert_by_name(wmOperatorType *ot)
void ANIM_OT_keyframe_delete(wmOperatorType *ot)
void ANIM_OT_keyingset_button_add(wmOperatorType *ot)
void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
void ANIM_OT_keying_set_remove(wmOperatorType *ot)
void ANIM_OT_paste_driver_button(wmOperatorType *ot)
Definition drivers.cc:1229
void ANIM_OT_keyframe_insert_button(wmOperatorType *ot)
void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
void ANIM_OT_copy_driver_button(wmOperatorType *ot)
Definition drivers.cc:1184
void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
void ANIM_OT_keyframe_delete_by_name(wmOperatorType *ot)
static int slot_new_for_object_exec(bContext *C, wmOperator *)
Definition anim_ops.cc:741
void ED_operatortypes_anim()
Definition anim_ops.cc:937
static void change_frame_apply(bContext *C, wmOperator *op, const bool always_update)
Definition anim_ops.cc:136
static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition anim_ops.cc:255
static int seq_frame_apply_snap(bContext *C, Scene *scene, const int timeline_frame)
Definition anim_ops.cc:114
static int convert_action_exec(bContext *C, wmOperator *)
Definition anim_ops.cc:777
static void ANIM_OT_previewrange_set(wmOperatorType *ot)
Definition anim_ops.cc:608
static bool anim_set_end_frames_poll(bContext *C)
Definition anim_ops.cc:436
static void ANIM_OT_previewrange_clear(wmOperatorType *ot)
Definition anim_ops.cc:663
static void ANIM_OT_convert_legacy_action(wmOperatorType *ot)
Definition anim_ops.cc:832
static bool use_sequencer_snapping(bContext *C)
Definition anim_ops.cc:221
static void change_frame_cancel(bContext *C, wmOperator *)
Definition anim_ops.cc:324
static int previewrange_clear_exec(bContext *C, wmOperator *)
Definition anim_ops.cc:640
static int anim_set_sfra_exec(bContext *C, wmOperator *op)
Definition anim_ops.cc:458
static int merge_actions_selection_exec(bContext *C, wmOperator *op)
Definition anim_ops.cc:865
static void seq_frame_snap_update_best(const int position, const int timeline_frame, int *r_best_frame, int *r_best_distance)
Definition anim_ops.cc:103
static void ANIM_OT_start_frame_set(wmOperatorType *ot)
Definition anim_ops.cc:498
static void ANIM_OT_slot_new_for_object(wmOperatorType *ot)
Definition anim_ops.cc:762
static void ANIM_OT_scene_range_frame(wmOperatorType *ot)
Definition anim_ops.cc:704
static bool merge_actions_selection_poll(bContext *C)
Definition anim_ops.cc:847
static int change_frame_exec(bContext *C, wmOperator *op)
Definition anim_ops.cc:176
static int anim_set_efra_exec(bContext *C, wmOperator *op)
Definition anim_ops.cc:513
static void ANIM_OT_end_frame_set(wmOperatorType *ot)
Definition anim_ops.cc:553
static int scene_range_frame_exec(bContext *C, wmOperator *)
Definition anim_ops.cc:685
static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event, SpaceSeq *sseq)
Definition anim_ops.cc:203
static bool sequencer_skip_for_handle_tweak(const bContext *C, const wmEvent *event)
Definition anim_ops.cc:233
static int previewrange_define_exec(bContext *C, wmOperator *op)
Definition anim_ops.cc:574
static bool slot_new_for_object_poll(bContext *C)
Definition anim_ops.cc:724
static float frame_from_event(bContext *C, const wmEvent *event)
Definition anim_ops.cc:186
static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition anim_ops.cc:341
void ED_keymap_anim(wmKeyConfig *keyconf)
Definition anim_ops.cc:983
static void ANIM_OT_merge_animation(wmOperatorType *ot)
Definition anim_ops.cc:917
static bool convert_action_poll(bContext *C)
Definition anim_ops.cc:811
static bool need_extra_redraw_after_scrubbing_ends(bContext *C)
Definition anim_ops.cc:290
static bool change_frame_poll(bContext *C)
Definition anim_ops.cc:58
static void ANIM_OT_change_frame(wmOperatorType *ot)
Definition anim_ops.cc:403
static void change_frame_seq_preview_end(SpaceSeq *sseq)
Definition anim_ops.cc:212
static int seq_snap_threshold_get_frame_distance(bContext *C)
Definition anim_ops.cc:95
unsigned int U
Definition btGjkEpa3.h:78
Slot & slot_add_for_id(const ID &animated_id)
const Slot * slot(int64_t index) const
void slot_name_set(Main &bmain, Slot &slot, StringRefNull new_name)
blender::Span< const Slot * > slots() const
Slot * slot_for_handle(slot_handle_t handle)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
VectorSet< Sequence * > SEQ_query_all_strips(ListBase *seqbase)
Definition iterator.cc:97
#define G(x, y, z)
Action * get_action(ID &animated_id)
void move_slot(Main &bmain, Slot &slot, Action &from_action, Action &to_action)
GPU_SHADER_INTERFACE_INFO(overlay_edit_curve_handle_iface, "vert").flat(Type pos vertex_in(1, Type::UINT, "data") .vertex_out(overlay_edit_curve_handle_iface) .geometry_layout(PrimitiveIn Frequency::GEOMETRY storage_buf(1, Qualifier::READ, "uint", "data[]", Frequency::GEOMETRY) .push_constant(Type Frequency::GEOMETRY selection[]
return ret
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition sequencer.cc:416
int SEQ_tool_settings_snap_distance_get(Scene *scene)
Definition sequencer.cc:392
short SEQ_tool_settings_snap_flag_get(Scene *scene)
Definition sequencer.cc:386
Editing * SEQ_editing_get(const Scene *scene)
Definition sequencer.cc:262
int SEQ_time_left_handle_frame_get(const Scene *, const Sequence *seq)
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
bAction * action
int32_t slot_handle
Definition DNA_ID.h:413
char name[66]
Definition DNA_ID.h:425
struct AnimData * adt
ID * owner_id
Definition RNA_types.hh:40
float xmax
float xmin
int xmin
int xmax
short val
Definition WM_types.hh:724
int mval[2]
Definition WM_types.hh:728
short type
Definition WM_types.hh:722
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
PropertyRNA * prop
Definition WM_types.hh:1092
const char * undo_group
Definition WM_types.hh:998
StructRNA * srna
Definition WM_types.hh:1080
void(* cancel)(bContext *C, wmOperator *op)
Definition WM_types.hh:1028
struct ReportList * reports
struct PointerRNA * ptr
bool ED_time_scrub_event_in_region(const ARegion *region, const wmEvent *event)
ccl_device_inline int abs(int x)
Definition util/math.h:120
void WM_main_add_notifier(uint type, void *reference)
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
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125
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.cc:897
void WM_operator_properties_border_to_rcti(wmOperator *op, rcti *r_rect)
void WM_operator_properties_border(wmOperatorType *ot)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
bScreen * WM_window_get_active_screen(const wmWindow *win)