Blender V4.5
anim_asset_ops.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_listbase.h"
6
7#include "BKE_asset.hh"
8#include "BKE_asset_edit.hh"
9#include "BKE_context.hh"
10#include "BKE_fcurve.hh"
11#include "BKE_global.hh"
12#include "BKE_icons.h"
13#include "BKE_lib_id.hh"
14#include "BKE_preferences.h"
15#include "BKE_report.hh"
16#include "BKE_screen.hh"
17
18#include "WM_api.hh"
19
20#include "RNA_access.hh"
21#include "RNA_define.hh"
22#include "RNA_prototypes.hh"
23
24#include "ED_asset.hh"
25#include "ED_asset_library.hh"
26#include "ED_asset_list.hh"
29#include "ED_asset_shelf.hh"
30#include "ED_fileselect.hh"
31#include "ED_screen.hh"
32#include "ED_undo.hh"
33
34#include "UI_interface_icons.hh"
35#include "UI_resources.hh"
36
37#include "BLT_translation.hh"
38
39#include "ANIM_action.hh"
41#include "ANIM_armature.hh"
42#include "ANIM_keyframing.hh"
43#include "ANIM_pose.hh"
44#include "ANIM_rna.hh"
45
46#include "AS_asset_catalog.hh"
48#include "AS_asset_library.hh"
50
51#include "anim_intern.hh"
52
54
56 PointerRNA * /*ptr*/,
57 PropertyRNA * /*prop*/,
58 bool *r_free)
59{
61 true);
62 *r_free = true;
63 BLI_assert(items != nullptr);
64 return items;
65}
66
68{
69 BLI_assert(bone_pointer.type == &RNA_PoseBone);
70
72 paths.append({"location"});
73 paths.append({"scale"});
74 bPoseChannel *pose_bone = static_cast<bPoseChannel *>(bone_pointer.data);
75 switch (pose_bone->rotmode) {
76 case ROT_MODE_QUAT:
77 paths.append({"rotation_quaternion"});
78 break;
80 paths.append({"rotation_axis_angle"});
81 break;
82 case ROT_MODE_XYZ:
83 case ROT_MODE_XZY:
84 case ROT_MODE_YXZ:
85 case ROT_MODE_YZX:
86 case ROT_MODE_ZXY:
87 case ROT_MODE_ZYX:
88 paths.append({"rotation_euler"});
89 default:
90 break;
91 }
92
93 paths.extend({{"bbone_curveinx"},
94 {"bbone_curveoutx"},
95 {"bbone_curveinz"},
96 {"bbone_curveoutz"},
97 {"bbone_rollin"},
98 {"bbone_rollout"},
99 {"bbone_scalein"},
100 {"bbone_scaleout"},
101 {"bbone_easein"},
102 {"bbone_easeout"}});
103
105
106 return paths;
107}
108
110 const blender::Span<Object *> pose_objects)
111{
112 /* This currently only looks at the pose and not other things that could go onto different
113 * slots on the same action. */
114
115 using namespace blender::animrig;
116 Action &action = action_add(bmain, "pose_create");
117 Layer &layer = action.layer_add("pose");
118 Strip &strip = layer.strip_add(action, Strip::Type::Keyframe);
119 StripKeyframeData &strip_data = strip.data<StripKeyframeData>(action);
121
122 for (Object *pose_object : pose_objects) {
123 BLI_assert(pose_object->pose);
124 Slot &slot = action.slot_add_for_id(pose_object->id);
125 const bArmature *armature = static_cast<bArmature *>(pose_object->data);
126
127 Set<RNAPath> existing_paths;
128 if (pose_object->adt && pose_object->adt->action &&
129 pose_object->adt->slot_handle != Slot::unassigned)
130 {
131 Action &pose_object_action = pose_object->adt->action->wrap();
132 const slot_handle_t pose_object_slot = pose_object->adt->slot_handle;
133 foreach_fcurve_in_action_slot(pose_object_action, pose_object_slot, [&](FCurve &fcurve) {
134 RNAPath existing_path = {fcurve.rna_path, std::nullopt, fcurve.array_index};
135 existing_paths.add(existing_path);
136 });
137 }
138
139 LISTBASE_FOREACH (bPoseChannel *, pose_bone, &pose_object->pose->chanbase) {
140 if (!(pose_bone->bone->flag & BONE_SELECTED) ||
141 !blender::animrig::bone_is_visible(armature, pose_bone->bone))
142 {
143 continue;
144 }
146 &pose_object->id, &RNA_PoseBone, pose_bone);
147 Vector<RNAPath> rna_paths = construct_pose_rna_paths(bone_pointer);
148 for (const RNAPath &rna_path : rna_paths) {
149 PointerRNA resolved_pointer;
150 PropertyRNA *resolved_property;
151 if (!RNA_path_resolve(
152 &bone_pointer, rna_path.path.c_str(), &resolved_pointer, &resolved_property))
153 {
154 continue;
155 }
156 const Vector<float> values = blender::animrig::get_rna_values(&resolved_pointer,
157 resolved_property);
158 const std::optional<std::string> rna_path_id_to_prop = RNA_path_from_ID_to_property(
159 &resolved_pointer, resolved_property);
160 if (!rna_path_id_to_prop.has_value()) {
161 continue;
162 }
163 for (const int i : values.index_range()) {
164 if (RNA_property_is_idprop(resolved_property) &&
165 !existing_paths.contains({rna_path_id_to_prop.value(), std::nullopt, i}))
166 {
167 /* Skipping custom properties without animation. */
168 continue;
169 }
170 strip_data.keyframe_insert(
171 &bmain, slot, {rna_path_id_to_prop.value(), i}, {1, values[i]}, key_settings);
172 }
173 }
174 }
175 }
176 return action;
177}
178
179/* Check that the newly created asset is visible SOMEWHERE in Blender. If not already visible,
180 * open the asset shelf on the current 3D view. The reason for not always doing that is that it
181 * might be annoying in case you have 2 3D viewports open, but you want the asset shelf on only one
182 * of them, or you work out of the asset browser.*/
184{
185 ScrArea *current_area = CTX_wm_area(&C);
186 if (!current_area || current_area->type->spaceid != SPACE_VIEW3D) {
187 /* Opening the asset shelf will only work from the 3D viewport. */
188 return;
189 }
190
192 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
193 const bScreen *screen = WM_window_get_active_screen(win);
194 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
195 if (area->type->spaceid == SPACE_FILE) {
196 SpaceFile *sfile = reinterpret_cast<SpaceFile *>(area->spacedata.first);
197 if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) {
198 /* Asset Browser is open. */
199 return;
200 }
201 continue;
202 }
203 const ARegion *shelf_region = BKE_area_find_region_type(area, RGN_TYPE_ASSET_SHELF);
204 if (!shelf_region) {
205 continue;
206 }
207 if (shelf_region->runtime->visible) {
208 /* A visible asset shelf was found. */
209 return;
210 }
211 }
212 }
213
214 /* At this point, no asset shelf or asset browser was visible anywhere. */
215 ARegion *shelf_region = BKE_area_find_region_type(current_area, RGN_TYPE_ASSET_SHELF);
216 if (!shelf_region) {
217 return;
218 }
219 shelf_region->flag &= ~RGN_FLAG_HIDDEN;
221}
222
224{
225 blender::Vector<PointerRNA> selected_objects;
226 CTX_data_selected_objects(C, &selected_objects);
227
228 blender::Vector<Object *> selected_pose_objects;
229 for (const PointerRNA &ptr : selected_objects) {
230 Object *object = reinterpret_cast<Object *>(ptr.owner_id);
231 if (!object->pose) {
232 continue;
233 }
234 selected_pose_objects.append(object);
235 }
236
237 Object *active_object = CTX_data_active_object(C);
238 /* The active object may not be selected, it should be added because you can still switch to pose
239 * mode. */
240 if (active_object && active_object->pose && !selected_pose_objects.contains(active_object)) {
241 selected_pose_objects.append(active_object);
242 }
243 return selected_pose_objects;
244}
245
247 wmOperator *op,
248 const StringRefNull name,
249 const AssetLibraryReference lib_ref)
250{
252
253 if (selected_pose_objects.is_empty()) {
254 return OPERATOR_CANCELLED;
255 }
256
257 Main *bmain = CTX_data_main(C);
258 /* Extract the pose into a new action. */
259 blender::animrig::Action &pose_action = extract_pose(*bmain, selected_pose_objects);
260 asset::mark_id(&pose_action.id);
261 if (!G.background) {
262 asset::generate_preview(C, &pose_action.id);
263 }
264 BKE_id_rename(*bmain, pose_action.id, name);
265
266 /* Add asset to catalog. */
267 char catalog_path_c[MAX_NAME];
268 RNA_string_get(op->ptr, "catalog_path", catalog_path_c);
269
270 AssetMetaData &meta_data = *pose_action.id.asset_data;
271 asset_system::AssetLibrary *library = AS_asset_library_load(bmain, lib_ref);
272 /* NOTE(@ChrisLend): I don't know if a local library can fail to load.
273 * Just being defensive here. */
274 BLI_assert(library);
275 if (catalog_path_c[0] && library) {
276 const asset_system::AssetCatalogPath catalog_path(catalog_path_c);
278 catalog_path);
279 BKE_asset_metadata_catalog_id_set(&meta_data, catalog.catalog_id, catalog.simple_name.c_str());
280 }
281
284
286
288
289 return OPERATOR_FINISHED;
290}
291
293 wmOperator *op,
294 const char name[MAX_NAME],
295 const AssetLibraryReference lib_ref)
296{
298 Main *bmain = CTX_data_main(C);
299
301 &U, lib_ref.custom_library_index);
302 BLI_assert_msg(user_library, "The passed lib_ref is expected to be a user library");
303 if (!user_library) {
304 return OPERATOR_CANCELLED;
305 }
306
307 asset_system::AssetLibrary *library = AS_asset_library_load(bmain, lib_ref);
308 if (!library) {
309 BKE_report(op->reports, RPT_ERROR, "Failed to load asset library");
310 return OPERATOR_CANCELLED;
311 }
312
314
315 if (selected_pose_objects.is_empty()) {
316 return OPERATOR_CANCELLED;
317 }
318
319 /* Temporary action in current main that will be exported and later deleted. */
320 blender::animrig::Action &pose_action = extract_pose(*bmain, selected_pose_objects);
321 asset::mark_id(&pose_action.id);
322 if (!G.background) {
323 asset::generate_preview(C, &pose_action.id);
324 }
325
326 /* Add asset to catalog. */
327 char catalog_path_c[MAX_NAME];
328 RNA_string_get(op->ptr, "catalog_path", catalog_path_c);
329
330 AssetMetaData &meta_data = *pose_action.id.asset_data;
331 if (catalog_path_c[0]) {
332 const asset_system::AssetCatalogPath catalog_path(catalog_path_c);
334 *library, catalog_path);
335 BKE_asset_metadata_catalog_id_set(&meta_data, catalog.catalog_id, catalog.simple_name.c_str());
336 }
337
338 AssetWeakReference pose_asset_reference;
339 const std::optional<std::string> final_full_asset_filepath = bke::asset_edit_id_save_as(
340 *bmain, pose_action.id, name, *user_library, pose_asset_reference, *op->reports);
341
342 library->catalog_service().write_to_disk(*final_full_asset_filepath);
345
346 BKE_id_free(bmain, &pose_action.id);
347
349
351
352 return OPERATOR_FINISHED;
353}
354
356{
357 char name[MAX_NAME] = "";
358 PropertyRNA *name_prop = RNA_struct_find_property(op->ptr, "pose_name");
359 if (RNA_property_is_set(op->ptr, name_prop)) {
360 RNA_property_string_get(op->ptr, name_prop, name);
361 }
362 if (name[0] == '\0') {
363 BKE_report(op->reports, RPT_ERROR, "No name set");
364 return OPERATOR_CANCELLED;
365 }
366
367 const int enum_value = RNA_enum_get(op->ptr, "asset_library_reference");
369
370 switch (lib_ref.type) {
372 return create_pose_asset_local(C, op, name, lib_ref);
373
375 return create_pose_asset_user_library(C, op, name, lib_ref);
376
377 default:
378 /* Only local and custom libraries should be exposed in the enum. */
380 break;
381 }
382
383 BKE_report(op->reports, RPT_ERROR, "Unexpected library type. Failed to create pose asset");
384
385 return OPERATOR_FINISHED;
386}
387
389 wmOperator *op,
390 const wmEvent * /*event*/)
391{
392 /* If the library isn't saved from the operator's last execution, use the first library. */
393 if (!RNA_struct_property_is_set_ex(op->ptr, "asset_library_reference", false)) {
395 *static_cast<const bUserAssetLibrary *>(U.asset_libraries.first));
396 RNA_enum_set(op->ptr,
397 "asset_library_reference",
399 }
400
401 return WM_operator_props_dialog_popup(C, op, 400, std::nullopt, IFACE_("Create"));
402}
403
405{
407 return false;
408 }
409 return true;
410}
411
413 const bContext *C,
415 PropertyRNA * /*prop*/,
416 const char *edit_text,
418{
419 const int enum_value = RNA_enum_get(ptr, "asset_library_reference");
421
423 *CTX_data_main(C), lib_ref, edit_text, visit_fn);
424}
425
427{
428 ot->name = "Create Pose Asset...";
429 ot->description = "Create a new asset from the selected bones in the scene";
430 ot->idname = "POSELIB_OT_create_pose_asset";
431
435
436 ot->prop = RNA_def_string(
437 ot->srna, "pose_name", nullptr, MAX_NAME, "Pose Name", "Name for the new pose asset");
438
439 PropertyRNA *prop = RNA_def_property(ot->srna, "asset_library_reference", PROP_ENUM, PROP_NONE);
441 RNA_def_property_ui_text(prop, "Library", "Asset library used to store the new pose");
442
443 prop = RNA_def_string(
444 ot->srna, "catalog_path", nullptr, MAX_NAME, "Catalog", "Catalog to use for the new asset");
447
448 /* This property is just kept to have backwards compatibility and has no functionality. It should
449 * be removed in the 5.0 release. */
450 prop = RNA_def_boolean(ot->srna,
451 "activate_new_action",
452 false,
453 "Activate New Action",
454 "This property is deprecated and will be removed in the future");
456}
457
464
467 "ADJUST",
468 0,
469 "Adjust",
470 "Update existing channels in the pose asset but don't remove or add any channels"},
472 "REPLACE",
473 0,
474 "Replace with Selection",
475 "Completely replace all channels in the pose asset with the current selection"},
476 {MODIFY_ADD,
477 "ADD",
478 0,
479 "Add Selected Bones",
480 "Add channels of the selection to the pose asset. Existing channels will be updated"},
482 "REMOVE",
483 0,
484 "Remove Selected Bones",
485 "Remove channels of the selection from the pose asset"},
486 {0, nullptr, 0, nullptr, nullptr},
487};
488
489/* Gets the selected asset from the given `bContext`. If the asset is an action, returns a pointer
490 * to that action, else returns a nullptr. */
492{
494 if (!asset) {
495 return nullptr;
496 }
497
498 if (asset->get_id_type() != ID_AC) {
499 return nullptr;
500 }
501
502 AssetWeakReference asset_reference = asset->make_weak_reference();
503 Main *bmain = CTX_data_main(C);
504 return reinterpret_cast<bAction *>(
505 bke::asset_edit_id_from_weak_reference(*bmain, ID_AC, asset_reference));
506}
507
512
514{
515 Vector<PathValue> path_values;
516 const bArmature *armature = static_cast<bArmature *>(pose_object.data);
517 LISTBASE_FOREACH (bPoseChannel *, pose_bone, &pose_object.pose->chanbase) {
518 if (!(pose_bone->bone->flag & BONE_SELECTED) ||
519 !blender::animrig::bone_is_visible(armature, pose_bone->bone))
520 {
521 continue;
522 }
524 &pose_object.id, &RNA_PoseBone, pose_bone);
525 Vector<RNAPath> rna_paths = construct_pose_rna_paths(bone_pointer);
526
527 for (RNAPath &rna_path : rna_paths) {
528 PointerRNA resolved_pointer;
529 PropertyRNA *resolved_property;
530 if (!RNA_path_resolve(
531 &bone_pointer, rna_path.path.c_str(), &resolved_pointer, &resolved_property))
532 {
533 continue;
534 }
535 const std::optional<std::string> rna_path_id_to_prop = RNA_path_from_ID_to_property(
536 &resolved_pointer, resolved_property);
537 if (!rna_path_id_to_prop.has_value()) {
538 continue;
539 }
540 Vector<float> values = blender::animrig::get_rna_values(&resolved_pointer,
541 resolved_property);
542 int i = 0;
543 for (const float value : values) {
544 RNAPath path = {rna_path_id_to_prop.value(), std::nullopt, i};
545 path_values.append({path, value});
546 i++;
547 }
548 }
549 }
550 return path_values;
551}
552
553static inline void replace_pose_key(Main &bmain,
555 const blender::animrig::Slot &slot,
556 const float2 time_value,
557 const blender::animrig::FCurveDescriptor &fcurve_descriptor)
558{
559 using namespace blender::animrig;
560 Channelbag &channelbag = strip_data.channelbag_for_slot_ensure(slot);
561 FCurve &fcurve = channelbag.fcurve_ensure(&bmain, fcurve_descriptor);
562
563 /* Clearing all keys beforehand in case the pose was not defined on frame defined in
564 * `time_value`. */
567 insert_vert_fcurve(&fcurve, time_value, key_settings, INSERTKEY_NOFLAGS);
568}
569
571 blender::animrig::Action &pose_action,
572 Object &pose_object,
573 const AssetModifyMode mode)
574{
575 using namespace blender::animrig;
576 /* The frame on which an FCurve has a key to define a pose. */
577 constexpr int pose_frame = 1;
578 if (pose_action.slot_array_num < 1) {
579 /* All actions should have slots at this point. */
581 return;
582 }
583
584 Slot &slot = blender::animrig::get_best_pose_slot_for_id(pose_object.id, pose_action);
585 BLI_assert(pose_action.strip_keyframe_data().size() == 1);
586 BLI_assert(pose_action.layers().size() == 1);
587 StripKeyframeData *strip_data = pose_action.strip_keyframe_data()[0];
588 Vector<PathValue> path_values = generate_path_values(pose_object);
589
590 Set<RNAPath> existing_paths;
591 foreach_fcurve_in_action_slot(pose_action, slot.handle, [&](FCurve &fcurve) {
592 existing_paths.add({fcurve.rna_path, std::nullopt, fcurve.array_index});
593 });
594
595 switch (mode) {
596 case MODIFY_ADJUST: {
597 for (const PathValue &path_value : path_values) {
598 /* Only updating existing channels. */
599 if (existing_paths.contains(path_value.rna_path)) {
600 replace_pose_key(*bmain,
601 *strip_data,
602 slot,
603 {pose_frame, path_value.value},
604 {path_value.rna_path.path, path_value.rna_path.index.value()});
605 }
606 }
607 break;
608 }
609 case MODIFY_ADD: {
610 for (const PathValue &path_value : path_values) {
611 replace_pose_key(*bmain,
612 *strip_data,
613 slot,
614 {pose_frame, path_value.value},
615 {path_value.rna_path.path, path_value.rna_path.index.value()});
616 }
617 break;
618 }
619 case MODIFY_REPLACE: {
620 Channelbag *channelbag = strip_data->channelbag_for_slot(slot.handle);
621 if (!channelbag) {
622 /* No channels to remove. */
623 return;
624 }
625 channelbag->fcurves_clear();
626 for (const PathValue &path_value : path_values) {
627 replace_pose_key(*bmain,
628 *strip_data,
629 slot,
630 {pose_frame, path_value.value},
631 {path_value.rna_path.path, path_value.rna_path.index.value()});
632 }
633 break;
634 }
635 case MODIFY_REMOVE: {
636 Channelbag *channelbag = strip_data->channelbag_for_slot(slot.handle);
637 if (!channelbag) {
638 /* No channels to remove. */
639 return;
640 }
641 Map<RNAPath, FCurve *> fcurve_map;
643 pose_action, pose_action.slot_array[0]->handle, [&](FCurve &fcurve) {
644 fcurve_map.add({fcurve.rna_path, std::nullopt, fcurve.array_index}, &fcurve);
645 });
646 for (const PathValue &path_value : path_values) {
647 if (existing_paths.contains(path_value.rna_path)) {
648 FCurve *fcurve = fcurve_map.lookup(path_value.rna_path);
649 channelbag->fcurve_remove(*fcurve);
650 }
651 }
652 break;
653 }
654 }
655}
656
658{
660 BLI_assert_msg(action, "Poll should have checked action exists");
661 /* Get asset now. Asset browser might get tagged for refreshing through operations below, and not
662 * allow querying items from context until refreshed, see #140781. */
664
665 Main *bmain = CTX_data_main(C);
666 Object *pose_object = CTX_data_active_object(C);
667 if (!pose_object || !pose_object->pose) {
668 return OPERATOR_CANCELLED;
669 }
670
671 AssetModifyMode mode = AssetModifyMode(RNA_enum_get(op->ptr, "mode"));
672 update_pose_action_from_scene(bmain, action->wrap(), *pose_object, mode);
673
674 if (ID_IS_LINKED(action)) {
675 /* Not needed for local assets. */
676 bke::asset_edit_id_save(*bmain, action->id, *op->reports);
677 }
678 else {
679 /* Only create undo-step for local actions. Undoing external files isn't supported. */
680 ED_undo_push_op(C, op);
681 }
682
685
686 return OPERATOR_FINISHED;
687}
688
690{
692 CTX_wm_operator_poll_msg_set(C, "Pose assets can only be modified from Pose Mode");
693 return false;
694 }
695
697
698 if (!action) {
699 return false;
700 }
701
702 if (!ID_IS_LINKED(action)) {
703 return true;
704 }
705
706 if (!bke::asset_edit_id_is_editable(action->id)) {
707 CTX_wm_operator_poll_msg_set(C, "Action is not editable");
708 return false;
709 }
710
711 if (!bke::asset_edit_id_is_writable(action->id)) {
712 CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
713 return false;
714 }
715
716 return true;
717}
718
719static std::string pose_asset_modify_description(bContext * /* C */,
720 wmOperatorType * /* ot */,
722{
723 const int mode = RNA_enum_get(ptr, "mode");
724 return std::string(prop_asset_overwrite_modes[mode].description);
725}
726
727/* Calling it overwrite instead of save because we aren't actually saving an opened asset. */
729{
730 ot->name = "Modify Pose Asset";
731 ot->description =
732 "Update the selected pose asset in the asset library from the currently selected bones. The "
733 "mode defines how the asset is updated";
734 ot->idname = "POSELIB_OT_asset_modify";
735
738 ot->get_description = pose_asset_modify_description;
739
740 RNA_def_enum(ot->srna,
741 "mode",
744 "Overwrite Mode",
745 "Specify which parts of the pose asset are overwritten");
746}
747
749{
751
752 if (!action) {
753 return false;
754 }
755
756 if (!ID_IS_LINKED(action)) {
757 return true;
758 }
759
760 if (!bke::asset_edit_id_is_editable(action->id)) {
761 CTX_wm_operator_poll_msg_set(C, "Action is not editable");
762 return false;
763 }
764
765 if (!bke::asset_edit_id_is_writable(action->id)) {
766 CTX_wm_operator_poll_msg_set(C, "Asset blend file is not editable");
767 return false;
768 }
769
770 return true;
771}
772
774{
776 if (!action) {
777 return OPERATOR_CANCELLED;
778 }
779
781 std::optional<AssetLibraryReference> library_ref =
782 asset->owner_asset_library().library_reference();
783
784 if (ID_IS_LINKED(action)) {
786 }
787 else {
788 asset::clear_id(&action->id);
789 /* Only create undo-step for local actions. Undoing external files isn't supported. */
790 ED_undo_push_op(C, op);
791 }
792
793 asset::refresh_asset_library(C, library_ref.value());
794
796
797 return OPERATOR_FINISHED;
798}
799
801 wmOperator *op,
802 const wmEvent * /*event*/)
803{
805
807 C,
808 op,
809 IFACE_("Delete Pose Asset"),
810 ID_IS_LINKED(action) ?
811 IFACE_("Permanently delete pose asset blend file? This cannot be undone.") :
812 IFACE_("The asset is local to the file. Deleting it will just clear the asset status."),
813 IFACE_("Delete"),
815 false);
816}
817
819{
820 ot->name = "Delete Pose Asset";
821 ot->description = "Delete the selected Pose Asset";
822 ot->idname = "POSELIB_OT_asset_delete";
823
827}
828
829} // namespace blender::ed::animrig
Functions and classes to work with Actions.
Functionality to iterate an Action in various ways.
Functions to deal with Armatures.
Functions to insert, delete or modify keyframes.
Functions to work with animation poses.
Helper functions for animation to interact with the RNA system.
blender::asset_system::AssetLibrary * AS_asset_library_load(const Main *bmain, const AssetLibraryReference &library_reference)
Main runtime representation of an asset.
void BKE_asset_metadata_catalog_id_set(AssetMetaData *asset_data, bUUID catalog_id, const char *catalog_simple_name)
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)
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)
void BKE_fcurve_delete_keys_all(FCurve *fcu)
void BKE_id_free(Main *bmain, void *idv)
IDNewNameResult BKE_id_rename(Main &bmain, ID &id, blender::StringRefNull name, const IDNewNameMode mode=IDNewNameMode::RenameExistingNever)
Definition lib_id.cc:2372
struct bUserAssetLibrary * BKE_preferences_asset_library_find_index(const struct UserDef *userdef, int index) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
ARegion * BKE_area_find_region_type(const ScrArea *area, int region_type)
Definition screen.cc:840
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define LISTBASE_FOREACH(type, var, list)
#define IFACE_(msgid)
@ ID_AC
@ ROT_MODE_XZY
@ ROT_MODE_QUAT
@ ROT_MODE_ZXY
@ ROT_MODE_AXISANGLE
@ ROT_MODE_ZYX
@ ROT_MODE_XYZ
@ ROT_MODE_YXZ
@ ROT_MODE_YZX
@ INSERTKEY_NOFLAGS
struct FCurve FCurve
@ BONE_SELECTED
@ ASSET_LIBRARY_CUSTOM
@ ASSET_LIBRARY_LOCAL
@ HD_AUTO
@ BEZT_IPO_BEZ
@ BEZT_KEYTYPE_KEYFRAME
@ RGN_TYPE_ASSET_SHELF
@ RGN_FLAG_HIDDEN
@ SPACE_FILE
@ SPACE_VIEW3D
@ FILE_BROWSE_MODE_ASSETS
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *region)
Definition area.cc:2355
bool ED_operator_posemode_context(bContext *C)
void ED_undo_push_op(bContext *C, wmOperator *op)
Definition ed_undo.cc:358
@ PROP_STRING_SEARCH_SUGGESTION
Definition RNA_types.hh:701
@ PROP_ENUM
Definition RNA_types.hh:154
@ PROP_SKIP_SAVE
Definition RNA_types.hh:330
@ PROP_HIDDEN
Definition RNA_types.hh:324
@ PROP_NONE
Definition RNA_types.hh:221
#define C
Definition RandGen.cpp:29
@ ALERT_ICON_WARNING
#define NA_ADDED
Definition WM_types.hh:583
#define NA_EDITED
Definition WM_types.hh:581
#define NC_ASSET
Definition WM_types.hh:401
#define NA_REMOVED
Definition WM_types.hh:584
#define ND_ASSET_LIST
Definition WM_types.hh:545
#define U
bool contains(const Key &key) const
Definition BLI_set.hh:310
bool add(const Key &key)
Definition BLI_set.hh:248
bool contains(const T &value) const
void append(const T &value)
bool is_empty() const
IndexRange index_range() const
void extend(Span< T > array)
Slot & slot_add_for_id(const ID &animated_id)
blender::Span< const Layer * > layers() const
Span< const StripKeyframeData * > strip_keyframe_data() const
Layer & layer_add(std::optional< StringRefNull > name)
bool fcurve_remove(FCurve &fcurve_to_remove)
FCurve & fcurve_ensure(Main *bmain, const FCurveDescriptor &fcurve_descriptor)
static constexpr slot_handle_t unassigned
SingleKeyingResult keyframe_insert(Main *bmain, const Slot &slot, const FCurveDescriptor &fcurve_descriptor, float2 time_value, const KeyframeSettings &settings, eInsertKeyFlags insert_key_flags=INSERTKEY_NOFLAGS, std::optional< float2 > cycle_range=std::nullopt)
Channelbag & channelbag_for_slot_ensure(const Slot &slot)
bool write_to_disk(const CatalogFilePath &blend_file_path)
AssetCatalogService & catalog_service() const
#define ID_IS_LINKED(_id)
#define MAX_NAME
#define G(x, y, z)
void foreach_fcurve_in_action_slot(Action &action, slot_handle_t handle, FunctionRef< void(FCurve &fcurve)> callback)
Action & action_add(Main &bmain, StringRefNull name)
bool bone_is_visible(const bArmature *armature, const Bone *bone)
Vector< RNAPath > get_keyable_id_property_paths(const PointerRNA &ptr)
Definition anim_rna.cc:126
Vector< float > get_rna_values(PointerRNA *ptr, PropertyRNA *prop)
Definition anim_rna.cc:25
decltype(::ActionSlot::handle) slot_handle_t
SingleKeyingResult insert_vert_fcurve(FCurve *fcu, const float2 position, const KeyframeSettings &settings, eInsertKeyFlags flag)
Main Key-framing API call.
Slot & get_best_pose_slot_for_id(const ID &id, Action &pose_data)
Definition pose.cc:161
ID * asset_edit_id_from_weak_reference(Main &global_main, ID_Type id_type, const AssetWeakReference &weak_ref)
std::optional< std::string > asset_edit_id_save_as(Main &global_main, const ID &id, StringRefNull name, const bUserAssetLibrary &user_library, AssetWeakReference &r_weak_ref, ReportList &reports)
bool asset_edit_id_delete(Main &global_main, ID &id, ReportList &reports)
bool asset_edit_id_is_writable(const ID &id)
bool asset_edit_id_is_editable(const ID &id)
bool asset_edit_id_save(Main &global_main, const ID &id, ReportList &reports)
static blender::Vector< Object * > get_selected_pose_objects(bContext *C)
static wmOperatorStatus pose_asset_delete_invoke(bContext *C, wmOperator *op, const wmEvent *)
static blender::animrig::Action & extract_pose(Main &bmain, const blender::Span< Object * > pose_objects)
static wmOperatorStatus pose_asset_delete_exec(bContext *C, wmOperator *op)
static bool pose_asset_delete_poll(bContext *C)
static void ensure_asset_ui_visible(bContext &C)
static bool pose_asset_create_poll(bContext *C)
static const EnumPropertyItem * rna_asset_library_reference_itemf(bContext *, PointerRNA *, PropertyRNA *, bool *r_free)
static Vector< PathValue > generate_path_values(Object &pose_object)
static wmOperatorStatus pose_asset_create_exec(bContext *C, wmOperator *op)
static wmOperatorStatus pose_asset_modify_exec(bContext *C, wmOperator *op)
void POSELIB_OT_asset_delete(wmOperatorType *ot)
static std::string pose_asset_modify_description(bContext *, wmOperatorType *, PointerRNA *ptr)
static wmOperatorStatus create_pose_asset_user_library(bContext *C, wmOperator *op, const char name[MAX_NAME], const AssetLibraryReference lib_ref)
static bool pose_asset_modify_poll(bContext *C)
void POSELIB_OT_create_pose_asset(wmOperatorType *ot)
static void replace_pose_key(Main &bmain, blender::animrig::StripKeyframeData &strip_data, const blender::animrig::Slot &slot, const float2 time_value, const blender::animrig::FCurveDescriptor &fcurve_descriptor)
static wmOperatorStatus pose_asset_create_invoke(bContext *C, wmOperator *op, const wmEvent *)
static Vector< RNAPath > construct_pose_rna_paths(const PointerRNA &bone_pointer)
static void update_pose_action_from_scene(Main *bmain, blender::animrig::Action &pose_action, Object &pose_object, const AssetModifyMode mode)
static void visit_library_prop_catalogs_catalog_for_search_fn(const bContext *C, PointerRNA *ptr, PropertyRNA *, const char *edit_text, FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
static wmOperatorStatus create_pose_asset_local(bContext *C, wmOperator *op, const StringRefNull name, const AssetLibraryReference lib_ref)
static const EnumPropertyItem prop_asset_overwrite_modes[]
void POSELIB_OT_asset_modify(wmOperatorType *ot)
static bAction * get_action_of_selected_asset(bContext *C)
void show_catalog_in_visible_shelves(const bContext &C, const StringRefNull catalog_path)
int library_reference_to_enum_value(const AssetLibraryReference *library)
const EnumPropertyItem * library_reference_to_rna_enum_itemf(bool include_readonly, bool include_current_file)
void refresh_asset_library(const bContext *C, const AssetLibraryReference &library_ref)
AssetLibraryReference library_reference_from_enum_value(int value)
void generate_preview(const bContext *C, ID *id)
void visit_library_catalogs_catalog_for_search(const Main &bmain, const AssetLibraryReference lib, const StringRef edit_text, const FunctionRef< void(StringPropertySearchVisitParams)> visit_fn)
void refresh_asset_library_from_asset(const bContext *C, const blender::asset_system::AssetRepresentation &asset)
AssetLibraryReference user_library_to_library_ref(const bUserAssetLibrary &user_library)
blender::asset_system::AssetCatalog & library_ensure_catalogs_in_path(blender::asset_system::AssetLibrary &library, const blender::asset_system::AssetCatalogPath &path)
VecBase< float, 2 > float2
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
bool RNA_property_is_idprop(const PropertyRNA *prop)
std::string RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_string_search_func_runtime(PropertyRNA *prop, StringPropertySearchFunc search_fn, const eStringPropertySearchFlag search_flag)
void RNA_def_property_ui_text(PropertyRNA *prop, const char *name, const char *description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier, int type, int subtype)
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)
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition rna_path.cc:1173
bool RNA_path_resolve(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition rna_path.cc:532
ARegionRuntimeHandle * runtime
The meta-data of an asset. By creating and giving this for a data-block (ID.asset_data),...
char * rna_path
int array_index
struct AssetMetaData * asset_data
Definition DNA_ID.h:413
struct bPose * pose
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
struct SpaceType * type
StripData * data
ListBase chanbase
ListBase areabase
struct ReportList * reports
struct PointerRNA * ptr
i
Definition text_draw.cc:230
void WM_main_add_notifier(uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4227
wmOperatorType * ot
Definition wm_files.cc:4226
wmOperatorStatus WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, std::optional< std::string > title, std::optional< std::string > confirm_text, const bool cancel_default)
wmOperatorStatus WM_operator_confirm_ex(bContext *C, wmOperator *op, const char *title, const char *message, const char *confirm_text, int icon, bool cancel_default)
bScreen * WM_window_get_active_screen(const wmWindow *win)