Blender V5.0
pose_lib_2.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstring>
10
12
13#include "MEM_guardedalloc.h"
14
15#include "BLT_translation.hh"
16
17#include "DNA_armature_types.h"
18
19#include "BKE_action.hh"
20#include "BKE_anim_data.hh"
21#include "BKE_animsys.h"
22#include "BKE_armature.hh"
23#include "BKE_context.hh"
24#include "BKE_lib_id.hh"
25#include "BKE_object.hh"
26#include "BKE_pose_backup.h"
27#include "BKE_report.hh"
28
29#include "DEG_depsgraph.hh"
30
31#include "RNA_access.hh"
32#include "RNA_define.hh"
33#include "RNA_prototypes.hh"
34
35#include "WM_api.hh"
36#include "WM_types.hh"
37
38#include "UI_interface.hh"
39
40#include "ED_asset.hh"
42#include "ED_keyframing.hh"
43#include "ED_screen.hh"
44#include "ED_util.hh"
45
46#include "ANIM_action.hh"
47#include "ANIM_action_legacy.hh"
48#include "ANIM_armature.hh"
49#include "ANIM_keyframing.hh"
50#include "ANIM_keyingsets.hh"
51#include "ANIM_pose.hh"
52#include "ANIM_rna.hh"
53
54#include "armature_intern.hh"
55
63
67
68 struct {
71
73
74 /* For temp-loading the Action from the pose library. */
75 AssetTempIDConsumer *temp_id_consumer;
76
77 /* Blend factor for interpolating between current and given pose.
78 * 1.0 means "100% pose asset". Negative values and values > 1.0 will be used as-is, and can
79 * cause interesting effects. */
83
84 blender::Vector<Object *> objects; /* Objects to work on. */
85 bAction *act; /* Pose to blend into the current pose. */
86 bAction *act_flipped; /* Flipped copy of `act`. */
87
88 Scene *scene; /* For auto-keying. */
89 ScrArea *area; /* For drawing status text. */
90
91 tSlider *slider; /* Slider UI and event handling. */
92
95};
96
102{
103 return pbd->is_flipped ? pbd->act_flipped : pbd->act;
104}
105
106/* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */
108{
109 bAction *action = poselib_action_to_blend(pbd);
111
112 if (pbd->state == POSE_BLEND_INIT) {
113 /* Ready for blending now. */
115 }
116}
117
118/* ---------------------------- */
119
120/* Auto-key/tag bones affected by the pose Action. */
122{
123 for (Object *ob : pbd->objects) {
125 return;
126 }
127
128 AnimData *adt = BKE_animdata_from_id(&ob->id);
129 if (adt != nullptr && adt->action != nullptr &&
131 {
132 /* Changes to linked-in Actions are not allowed. */
133 return;
134 }
135
136 bPose *pose = ob->pose;
138 const bArmature *armature = static_cast<const bArmature *>(ob->data);
139
141 act->wrap());
142
143 /* Storing which pose bones were already keyed since multiple FCurves will probably exist per
144 * pose bone. */
145 blender::Set<bPoseChannel *> keyed_pose_bones;
146 auto autokey_pose_bones = [&](FCurve * /* fcu */, const char *bone_name) {
147 bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone_name);
148 if (!pchan) {
149 /* This bone cannot be found any more. This is fine, this can happen
150 * when F-Curves for a bone are included in a pose asset, and later the
151 * bone itself was renamed or removed. */
152 return;
153 }
155 !blender::animrig::bone_is_selected(armature, pchan))
156 {
157 return;
158 }
159 if (keyed_pose_bones.contains(pchan)) {
160 return;
161 }
162 /* This mimics the Whole Character Keying Set that was used here previously. In the future we
163 * could only key rna paths of FCurves that are actually in the applied pose. */
164 PointerRNA pose_bone_pointer = RNA_pointer_create_discrete(&ob->id, &RNA_PoseBone, pchan);
166 pose_bone_pointer);
167 rna_paths.append({"location"});
169 eRotationModes(pchan->rotmode));
170 rna_paths.append({rotation_mode_path});
171 rna_paths.append({"scale"});
172 blender::animrig::autokeyframe_pose_channel(C, scene, ob, pchan, rna_paths, 0);
173 keyed_pose_bones.add(pchan);
174 };
175 blender::bke::BKE_action_find_fcurves_with_bones(act, slot.handle, autokey_pose_bones);
176 }
177
178 /* send notifiers for this */
180}
181
182/* Apply the relevant changes to the pose */
184{
185 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
186
187 if (!pbd->needs_redraw) {
188 return;
189 }
190 pbd->needs_redraw = false;
191
193
194 /* The pose needs updating, whether it's for restoring the original pose or for showing the
195 * result of the blend. */
196 for (Object *ob : pbd->objects) {
199 }
200
201 if (pbd->state != POSE_BLEND_BLENDING) {
202 return;
203 }
204
205 /* Perform the actual blending. */
208 blender::animrig::Action &pose_action = poselib_action_to_blend(pbd)->wrap();
209 if (pose_action.slot_array_num == 0) {
210 return;
211 }
212
214 pbd->objects, pose_action, &anim_eval_context, pbd->blend_factor);
215}
216
217/* ---------------------------- */
218
219static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor)
220{
221 pbd->blend_factor = new_factor;
222 pbd->needs_redraw = true;
223}
224
226{
227 /* The pose will toggle between flipped and normal. This means the pose
228 * backup has to change, as it only contains the bones for one side. */
231
232 pbd->is_flipped = !pbd->is_flipped;
233 pbd->needs_redraw = true;
234
236}
237
238/* Return operator return value. */
240 wmOperator *op,
241 const wmEvent *event)
242{
243 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
244
245 ED_slider_modal(pbd->slider, event);
246 const float factor = ED_slider_factor_get(pbd->slider);
247 poselib_blend_set_factor(pbd, factor);
248
249 if (event->type == MOUSEMOVE) {
251 }
252
253 /* Handle the release confirm event directly, it has priority over others. */
255 (event->type == pbd->release_confirm_info.init_event_type) && (event->val == KM_RELEASE))
256 {
259 }
260
261 /* Ctrl manages the 'flipped' state. It works as a toggle so if the operator started in flipped
262 * mode, pressing it will unflip the pose. */
263 if (ELEM(event->val, KM_PRESS, KM_RELEASE) &&
265 {
267 }
268
269 /* only accept 'press' event, and ignore 'release', so that we don't get double actions */
270 if (ELEM(event->val, KM_PRESS, KM_NOTHING) == 0) {
272 }
273
274 /* NORMAL EVENT HANDLING... */
275 /* searching takes priority over normal activity */
276 switch (event->type) {
277 /* Exit - cancel. */
278 case EVT_ESCKEY:
279 case RIGHTMOUSE:
281 break;
282
283 /* Exit - confirm. */
284 case LEFTMOUSE:
285 case EVT_RETKEY:
286 case EVT_PADENTER:
287 case EVT_SPACEKEY:
289 break;
290
291 /* TODO(Sybren): toggle between original pose and poselib pose. */
292 case EVT_TABKEY:
294 pbd->needs_redraw = true;
295 break;
296 default: {
297 break;
298 }
299 }
300
302}
303
304/* ---------------------------- */
305
307{
308 blender::Vector<PointerRNA> selected_objects;
309 CTX_data_selected_objects(&C, &selected_objects);
310
311 blender::Vector<Object *> selected_pose_objects;
312 for (const PointerRNA &ptr : selected_objects) {
313 Object *object = reinterpret_cast<Object *>(ptr.owner_id);
314 if (!object || !object->pose) {
315 continue;
316 }
317 selected_pose_objects.append(object);
318 }
319
320 Object *active_object = CTX_data_active_object(&C);
321 /* The active object may not be selected, it should be added because you can still switch to pose
322 * mode. */
323 if (active_object && active_object->pose && !selected_pose_objects.contains(active_object)) {
324 selected_pose_objects.append(active_object);
325 }
326 return selected_pose_objects;
327}
328
330{
331 using namespace blender::ed;
333}
334
336{
337 using namespace blender::ed;
338
340
343 *C, *op->ptr, op->reports);
344 if (!asset) {
345 /* Explicit asset reference passed, but cannot be found. Error out. */
347 RPT_ERROR,
348 "Asset not found: '%s'",
349 RNA_string_get(op->ptr, "relative_asset_identifier").c_str());
350 return nullptr;
351 }
352 }
353 else {
354 /* If no explicit asset reference was passed, get asset from context. */
356 if (!asset) {
357 BKE_report(op->reports, RPT_ERROR, "No asset in context");
358 return nullptr;
359 }
360 }
361
362 if (asset->get_id_type() != ID_AC) {
364 RPT_ERROR,
365 "Asset ('%s') is not an action data-block",
366 asset->get_name().c_str());
367 return nullptr;
368 }
369
370 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
371
373 return reinterpret_cast<bAction *>(asset::temp_id_consumer_ensure_local_id(
375}
376
378{
379 bAction *action_copy = reinterpret_cast<bAction *>(
380 BKE_id_copy_ex(nullptr, &action->id, nullptr, LIB_ID_COPY_LOCALIZE));
381
382 /* Lock the window manager while flipping the pose. Flipping requires temporarily modifying the
383 * pose, which can cause unwanted visual glitches. */
385 const bool interface_was_locked = CTX_wm_interface_locked(C);
387
388 BKE_action_flip_with_pose(action_copy, objects);
389
390 WM_locked_interface_set(wm, interface_was_locked);
391 return action_copy;
392}
393
394/* Return true on success, false if the context isn't suitable. */
395static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *event)
396{
397 op->customdata = nullptr;
398
399 /* check if valid poselib */
400 blender::Vector<Object *> selected_pose_objects = get_poselib_objects(*C);
401 if (selected_pose_objects.is_empty()) {
402 BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode");
403 return false;
404 }
405
406 /* Set up blend state info. */
407 PoseBlendData *pbd;
408 op->customdata = pbd = MEM_new<PoseBlendData>("PoseLib Preview Data");
409
411 if (pbd->act == nullptr) {
412 /* No report here. The poll function cannot check if the operator properties have an asset
413 * reference to determine the asset to operate on, in which case we fallback to getting the
414 * asset from context. */
415 return false;
416 }
417 if (pbd->act->wrap().slots().size() == 0) {
418 BKE_report(op->reports, RPT_ERROR, "This pose asset is empty, and thus has no pose");
419 return false;
420 }
421
422 pbd->is_flipped = RNA_struct_property_is_set(op->ptr, "flipped") ?
423 RNA_boolean_get(op->ptr, "flipped") :
424 (event && (event->modifier & KM_CTRL));
425 pbd->blend_factor = RNA_float_get(op->ptr, "blend_factor");
426
427 /* Only construct the flipped pose if there is a chance it's actually needed. */
428 const bool is_interactive = (event != nullptr);
429 if (is_interactive || pbd->is_flipped) {
430 pbd->act_flipped = flip_pose(C, selected_pose_objects, pbd->act);
431 }
432
433 /* Get the basic data. */
434 pbd->objects = selected_pose_objects;
435
436 pbd->scene = CTX_data_scene(C);
437 pbd->area = CTX_wm_area(C);
438
439 pbd->state = POSE_BLEND_INIT;
440 pbd->needs_redraw = true;
441
442 /* Just to avoid a clang-analyzer warning (false positive), it's set properly below. */
444
445 /* Release confirm data. Only available if there's an event to work with. */
446 if (is_interactive) {
447 PropertyRNA *release_confirm_prop = RNA_struct_find_property(op->ptr, "release_confirm");
448 if (release_confirm_prop && RNA_property_is_set(op->ptr, release_confirm_prop)) {
450 op->ptr, release_confirm_prop);
451 }
452 else {
454 }
455
456 pbd->slider = ED_slider_create(C);
457 ED_slider_init(pbd->slider, event);
459 ED_slider_allow_overshoot_set(pbd->slider, true, true);
462 }
463
465 BLI_assert(is_interactive);
467 event->type);
468 }
469
470 /* Make backups for blending and restoring the pose. */
472
473 /* Set pose flags to ensure the depsgraph evaluation doesn't overwrite it. */
474 for (Object *ob : selected_pose_objects) {
475 ob->pose->flag &= ~POSE_DO_UNLOCK;
476 ob->pose->flag |= POSE_LOCKED;
477 }
478
479 return true;
480}
481
483{
484 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
485 wmWindow *win = CTX_wm_window(C);
486
487 /* Redraw the header so that it doesn't show any of our stuff anymore. */
488 ED_area_status_text(pbd->area, nullptr);
489 ED_workspace_status_text(C, nullptr);
490
491 if (pbd->slider) {
493 }
494
495 /* This signals the depsgraph to unlock and reevaluate the pose on the next evaluation. */
496 for (Object *ob : pbd->objects) {
497 bPose *pose = ob->pose;
498 pose->flag |= POSE_DO_UNLOCK;
499 }
500
501 switch (pbd->state) {
502 case POSE_BLEND_CONFIRM: {
503 Scene *scene = pbd->scene;
504 poselib_keytag_pose(C, scene, pbd);
505
506 /* Ensure the redo panel has the actually-used value, instead of the initial value. */
507 RNA_float_set(op->ptr, "blend_factor", pbd->blend_factor);
508 RNA_boolean_set(op->ptr, "flipped", pbd->is_flipped);
509 break;
510 }
511
512 case POSE_BLEND_INIT:
515 /* Cleanup should not be called directly from these states. */
516 BLI_assert_msg(0, "poselib_blend_cleanup: unexpected pose blend state");
517 BKE_report(op->reports, RPT_ERROR, "Internal pose library error, canceling operator");
521 break;
522 }
523
524 for (Object *ob : pbd->objects) {
527 }
528 /* Update mouse-hover highlights. */
530}
531
533{
534 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
535 if (pbd == nullptr) {
536 return;
537 }
538
539 if (pbd->act_flipped) {
540 BKE_id_free(nullptr, pbd->act_flipped);
541 }
543
544 /* Free temp data for operator */
546 pbd->pose_backup = nullptr;
547
548 MEM_delete(pbd);
549}
550
552{
553 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
554 const ePoseBlendState exit_state = pbd->state;
555
558
559 wmWindow *win = CTX_wm_window(C);
561
562 if (exit_state == POSE_BLEND_CANCEL) {
563 return OPERATOR_CANCELLED;
564 }
565 return OPERATOR_FINISHED;
566}
567
568/* Cancel previewing operation (called when exiting Blender) */
570{
571 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
574}
575
576/* Main modal status check. */
578{
579 const wmOperatorStatus operator_result = poselib_blend_handle_event(C, op, event);
580
581 const PoseBlendData *pbd = static_cast<const PoseBlendData *>(op->customdata);
583 return poselib_blend_exit(C, op);
584 }
585
586 if (pbd->needs_redraw) {
587
589
590 if (pbd->state == POSE_BLEND_BLENDING) {
591 status.item(IFACE_("Show Original Pose"), ICON_EVENT_TAB);
592 }
593 else {
594 status.item(IFACE_("Show Blended Pose"), ICON_EVENT_TAB);
595 }
596
598
599 status.item_bool(IFACE_("Flip Pose"), pbd->is_flipped, ICON_EVENT_CTRL);
600
602 }
603
604 return operator_result;
605}
606
608{
609 if (!poselib_blend_init_data(C, op, event)) {
611 return OPERATOR_CANCELLED;
612 }
613
615
616 PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
618 return poselib_blend_exit(C, op);
619}
620
622{
623 return poselib_apply_invoke(C, op, nullptr);
624}
625
626/* Modal Operator init. */
628{
629 if (!poselib_blend_init_data(C, op, event)) {
631 return OPERATOR_CANCELLED;
632 }
633
634 wmWindow *win = CTX_wm_window(C);
636
637 /* Do initial apply to have something to look at. */
639
642}
643
644/* Single-shot apply. */
646{
647 return poselib_apply_invoke(C, op, nullptr);
648}
649
650/* Poll callback for operators that require existing PoseLib data (with poses) to work. */
652{
653 blender::Span<Object *> selected_pose_objects = get_poselib_objects(*C);
654 if (selected_pose_objects.is_empty()) {
655 /* Pose lib is only for armatures in pose mode. */
656 return false;
657 }
658
659 return true;
660}
661
662/* Operator properties can set an asset reference to determine the asset to operate on (the pose
663 * can then be applied via shortcut too, for example). If this isn't set, an active asset from
664 * context is queried. */
666{
667 PropertyRNA *prop;
668
669 /* Identifiers: */
670 ot->name = "Apply Pose Asset";
671 ot->idname = "POSELIB_OT_apply_pose_asset";
672 ot->description = "Apply the given Pose Action to the rig";
673
674 /* Callbacks: */
675 ot->invoke = poselib_apply_invoke;
676 ot->exec = poselib_apply_exec;
677 ot->poll = poselib_blend_poll;
678
679 /* Flags: */
681
682 /* Properties: */
685 "blend_factor",
686 1.0f,
687 -FLT_MAX,
688 FLT_MAX,
689 "Blend Factor",
690 "Amount that the pose is applied on top of the existing poses. A negative "
691 "value will subtract the pose instead of adding it",
692 -1.0f,
693 1.0f);
694 prop = RNA_def_boolean(ot->srna,
695 "flipped",
696 false,
697 "Apply Flipped",
698 "When enabled, applies the pose flipped over the X-axis");
700}
701
702/* See comment on #POSELIB_OT_apply_pose_asset. */
704{
705 PropertyRNA *prop;
706
707 /* Identifiers: */
708 ot->name = "Blend Pose Asset";
709 ot->idname = "POSELIB_OT_blend_pose_asset";
710 ot->description = "Blend the given Pose Action to the rig";
711
712 /* Callbacks: */
713 ot->invoke = poselib_blend_invoke;
714 ot->modal = poselib_blend_modal;
715 ot->cancel = poselib_blend_cancel;
716 ot->exec = poselib_blend_exec;
717 ot->poll = poselib_blend_poll;
718
719 /* Flags: */
721
722 /* Properties: */
724 prop = RNA_def_float_factor(ot->srna,
725 "blend_factor",
726 0.0f,
727 -FLT_MAX,
728 FLT_MAX,
729 "Blend Factor",
730 "Amount that the pose is applied on top of the existing poses. A "
731 "negative value will subtract the pose instead of adding it",
732 -1.0f,
733 1.0f);
734 /* Blending should always start at 0%, and not at whatever percentage was last used. This RNA
735 * property just exists for symmetry with the Apply operator (and thus simplicity of the rest of
736 * the code, which can assume this property exists). */
738
739 prop = RNA_def_boolean(ot->srna,
740 "flipped",
741 false,
742 "Apply Flipped",
743 "When enabled, applies the pose flipped over the X-axis");
745
746 prop = RNA_def_boolean(ot->srna,
747 "release_confirm",
748 false,
749 "Confirm on Release",
750 "Always confirm operation when releasing button");
752}
Functions and classes to work with Actions.
Functions for backward compatibility with the legacy Action API.
Functions to deal with Armatures.
Functions to insert, delete or modify keyframes.
Functionality to interact with keying sets.
Functions to work with animation poses.
Helper functions for animation to interact with the RNA system.
Main runtime representation of an asset.
Blender kernel action and pose functionality.
void void void void void BKE_action_flip_with_pose(bAction *act, blender::Span< Object * > objects) ATTR_NONNULL(1)
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
AnimData * BKE_animdata_from_id(const ID *id)
Definition anim_data.cc:83
AnimationEvalContext BKE_animsys_eval_context_construct(struct Depsgraph *depsgraph, float eval_time) ATTR_WARN_UNUSED_RESULT
Definition anim_sys.cc:738
bool CTX_wm_interface_locked(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
class blender::asset_system::AssetRepresentation * CTX_wm_asset(const bContext *C)
bool CTX_data_selected_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Main * CTX_data_main(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:2523
void BKE_id_free(Main *bmain, void *idv)
ID * BKE_id_copy_ex(Main *bmain, const ID *id, ID **new_id_p, int flag)
Definition lib_id.cc:777
@ LIB_ID_COPY_LOCALIZE
General operations, lookup, etc. for blender objects.
struct PoseBackup * BKE_pose_backup_create_selected_bones(blender::Span< Object * > objects, const struct bAction *action) ATTR_WARN_UNUSED_RESULT
void BKE_pose_backup_restore(const struct PoseBackup *pbd)
bool BKE_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup)
void BKE_pose_backup_free(struct PoseBackup *pbd)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define ATTR_FALLTHROUGH
#define ELEM(...)
#define IFACE_(msgid)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ ID_AC
eRotationModes
@ POSE_LOCKED
@ POSE_DO_UNLOCK
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_area_status_text(ScrArea *area, const char *str)
Definition area.cc:851
void ED_workspace_status_text(bContext *C, const char *str)
Definition area.cc:1024
void ED_slider_init(tSlider *slider, const wmEvent *event)
Definition ed_draw.cc:477
void ED_slider_allow_overshoot_set(tSlider *slider, bool lower, bool upper)
Definition ed_draw.cc:616
void ED_slider_destroy(bContext *C, tSlider *slider)
Definition ed_draw.cc:579
void ED_slider_allow_increments_set(tSlider *slider, bool value)
Definition ed_draw.cc:627
tSlider * ED_slider_create(bContext *C)
Definition ed_draw.cc:433
bool ED_slider_modal(tSlider *slider, const wmEvent *event)
Definition ed_draw.cc:482
void ED_slider_status_get(const tSlider *slider, WorkspaceStatus &status)
Definition ed_draw.cc:563
void ED_slider_factor_bounds_set(tSlider *slider, float factor_bound_lower, float factor_bound_upper)
Definition ed_draw.cc:632
float ED_slider_factor_get(const tSlider *slider)
Definition ed_draw.cc:592
void ED_slider_factor_set(tSlider *slider, float factor)
Definition ed_draw.cc:597
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
@ PROP_HIDDEN
Definition RNA_types.hh:338
#define C
Definition RandGen.cpp:29
#define UI_MAX_DRAW_STR
@ KM_CTRL
Definition WM_types.hh:279
@ KM_NOTHING
Definition WM_types.hh:310
@ KM_PRESS
Definition WM_types.hh:311
@ KM_RELEASE
Definition WM_types.hh:312
#define NC_ANIMATION
Definition WM_types.hh:388
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
@ OPTYPE_GRAB_CURSOR_X
Definition WM_types.hh:190
#define ND_POSE
Definition WM_types.hh:458
#define NA_EDITED
Definition WM_types.hh:584
#define ND_KEYFRAME
Definition WM_types.hh:494
#define NC_OBJECT
Definition WM_types.hh:379
BPy_StructRNA * depsgraph
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool add(const Key &key)
Definition BLI_set.hh:248
constexpr bool is_empty() const
Definition BLI_span.hh:260
bool contains(const T &value) const
void append(const T &value)
bool is_empty() const
bool autokeyframe_cfra_can_key(const Scene *scene, ID *id)
Vector< RNAPath > get_keyable_id_property_paths(const PointerRNA &ptr)
Definition anim_rna.cc:126
bool bone_is_selected(const bArmature *armature, const Bone *bone)
void pose_apply_action(blender::Span< Object * > objects, Action &pose_action, const AnimationEvalContext *anim_eval_context, float blend_factor)
StringRef get_rotation_mode_path(eRotationModes rotation_mode)
Definition anim_rna.cc:82
Slot & get_best_pose_slot_for_id(const ID &id, Action &pose_data)
Definition pose.cc:160
void autokeyframe_pose_channel(bContext *C, Scene *scene, Object *ob, bPoseChannel *pose_channel, Span< RNAPath > rna_paths, short targetless_ik)
void BKE_action_find_fcurves_with_bones(bAction *action, blender::animrig::slot_handle_t slot_handle, FoundFCurveCallback callback)
void operator_asset_reference_props_register(StructRNA &srna)
AssetTempIDConsumer * temp_id_consumer_create(const blender::asset_system::AssetRepresentation *asset)
const asset_system::AssetRepresentation * operator_asset_reference_props_get_asset_from_all_library(const bContext &C, PointerRNA &ptr, ReportList *reports)
ID * temp_id_consumer_ensure_local_id(AssetTempIDConsumer *consumer, ID_Type id_type, Main *bmain, ReportList *reports)
bool operator_asset_reference_props_is_set(PointerRNA &ptr)
void temp_id_consumer_free(AssetTempIDConsumer **consumer)
static wmOperatorStatus poselib_blend_exit(bContext *C, wmOperator *op)
static wmOperatorStatus poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event)
static bAction * poselib_action_to_blend(PoseBlendData *pbd)
static wmOperatorStatus poselib_blend_handle_event(bContext *, wmOperator *op, const wmEvent *event)
static void poselib_blend_cleanup(bContext *C, wmOperator *op)
static bool poselib_blend_poll(bContext *C)
static void poselib_blend_cancel(bContext *C, wmOperator *op)
static wmOperatorStatus poselib_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void poselib_blend_apply(bContext *C, wmOperator *op)
void POSELIB_OT_apply_pose_asset(wmOperatorType *ot)
static wmOperatorStatus poselib_blend_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bAction * poselib_blend_init_get_action(bContext *C, wmOperator *op)
static void poselib_tempload_exit(PoseBlendData *pbd)
static void poselib_backup_posecopy(PoseBlendData *pbd)
static void poselib_keytag_pose(bContext *C, Scene *scene, PoseBlendData *pbd)
static wmOperatorStatus poselib_apply_exec(bContext *C, wmOperator *op)
static void poselib_blend_free(wmOperator *op)
void POSELIB_OT_blend_pose_asset(wmOperatorType *ot)
static wmOperatorStatus poselib_blend_exec(bContext *C, wmOperator *op)
static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor)
static blender::Vector< Object * > get_poselib_objects(bContext &C)
static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *event)
static bAction * flip_pose(bContext *C, blender::Span< Object * > objects, bAction *action)
static void poselib_toggle_flipped(PoseBlendData *pbd)
ePoseBlendState
Definition pose_lib_2.cc:56
@ POSE_BLEND_CANCEL
Definition pose_lib_2.cc:61
@ POSE_BLEND_CONFIRM
Definition pose_lib_2.cc:60
@ POSE_BLEND_ORIGINAL
Definition pose_lib_2.cc:59
@ POSE_BLEND_INIT
Definition pose_lib_2.cc:57
@ POSE_BLEND_BLENDING
Definition pose_lib_2.cc:58
const int status
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
float RNA_float_get(PointerRNA *ptr, const char *name)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
PropertyRNA * RNA_def_float_factor(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)
#define FLT_MAX
Definition stdcycles.h:14
bAction * action
struct bPose * pose
PoseBackup * pose_backup
Definition pose_lib_2.cc:82
bAction * act_flipped
Definition pose_lib_2.cc:86
AssetTempIDConsumer * temp_id_consumer
Definition pose_lib_2.cc:75
Scene * scene
Definition pose_lib_2.cc:88
char headerstr[UI_MAX_DRAW_STR]
Definition pose_lib_2.cc:94
blender::Vector< Object * > objects
Definition pose_lib_2.cc:84
ScrArea * area
Definition pose_lib_2.cc:89
tSlider * slider
Definition pose_lib_2.cc:91
ePoseBlendState state
Definition pose_lib_2.cc:65
bool use_release_confirm
Definition pose_lib_2.cc:69
bAction * act
Definition pose_lib_2.cc:85
float blend_factor
Definition pose_lib_2.cc:80
struct PoseBlendData::@364151073147177316020310160004314352306037157112 release_confirm_info
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
struct ReportList * reports
struct PointerRNA * ptr
void WM_cursor_modal_set(wmWindow *win, int val)
void WM_cursor_modal_restore(wmWindow *win)
@ WM_CURSOR_EW_SCROLL
Definition wm_cursors.hh:54
int WM_userdef_event_type_from_keymap_type(int kmitype)
void WM_locked_interface_set(wmWindowManager *wm, bool lock)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_event_add_mousemove(wmWindow *win)
@ RIGHTMOUSE
@ EVT_RIGHTCTRLKEY
@ EVT_TABKEY
@ EVT_LEFTCTRLKEY
@ EVT_PADENTER
@ EVT_SPACEKEY
@ MOUSEMOVE
@ LEFTMOUSE
@ EVT_ESCKEY
@ EVT_RETKEY
PointerRNA * ptr
Definition wm_files.cc:4238
wmOperatorType * ot
Definition wm_files.cc:4237