2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Ton Roosendaal, Blender Foundation '05, full recode.
23 * Reevan McKay (original NaN code)
25 * ***** END GPL LICENSE BLOCK *****
27 * Pose Mode API's and Operators for Pose Mode armatures
30 /** \file blender/editors/armature/pose_edit.c
35 #include "BLI_blenlib.h"
37 #include "DNA_anim_types.h"
38 #include "DNA_armature_types.h"
39 #include "DNA_constraint_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_object_types.h"
44 #include "BKE_action.h"
45 #include "BKE_armature.h"
46 #include "BKE_context.h"
47 #include "BKE_deform.h"
48 #include "BKE_depsgraph.h"
49 #include "BKE_object.h"
50 #include "BKE_report.h"
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54 #include "RNA_enum_types.h"
59 #include "ED_armature.h"
60 #include "ED_keyframing.h"
61 #include "ED_screen.h"
62 #include "ED_object.h"
64 #include "UI_interface.h"
66 #include "armature_intern.h"
68 /* matches logic with ED_operator_posemode_context() */
69 Object *ED_pose_object_from_context(bContext *C)
71 ScrArea *sa = CTX_wm_area(C);
74 /* since this call may also be used from the buttons window, we need to check for where to get the object */
75 if (sa && sa->spacetype == SPACE_BUTS) {
76 ob = ED_object_context(C);
79 ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
85 /* This function is used to process the necessary updates for */
86 void ED_armature_enter_posemode(bContext *C, Base *base)
88 ReportList *reports = CTX_wm_reports(C);
89 Object *ob = base->object;
92 BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
98 ob->restore_mode = ob->mode;
99 ob->mode |= OB_MODE_POSE;
101 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
108 /* XXX: disabled as this would otherwise cause a nasty loop... */
109 //ED_object_toggle_modes(C, ob->mode);
112 void ED_armature_exit_posemode(bContext *C, Base *base)
115 Object *ob = base->object;
117 ob->restore_mode = ob->mode;
118 ob->mode &= ~OB_MODE_POSE;
120 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
124 /* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
125 /* only_selected == 1: the active bone is allowed to be protected */
126 #if 0 /* UNUSED 2.5 */
127 static bool pose_has_protected_selected(Object *ob, short warn)
129 /* check protection */
132 bArmature *arm = ob->data;
134 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
135 if (pchan->bone && (pchan->bone->layer & arm->layer)) {
136 if (pchan->bone->layer & arm->layer_protected) {
137 if (pchan->bone->flag & BONE_SELECTED)
143 if (warn) error("Cannot change Proxy protected bones");
151 /* ********************************************** */
154 /* For the object with pose/action: update paths for those that have got them
155 * This should selectively update paths that exist...
157 * To be called from various tools that do incremental updates
159 void ED_pose_recalculate_paths(Scene *scene, Object *ob)
161 ListBase targets = {NULL, NULL};
163 /* set flag to force recalc, then grab the relevant bones to target */
164 ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
165 animviz_get_object_motionpaths(ob, &targets);
167 /* recalculate paths, then free */
168 animviz_calc_motionpaths(scene, &targets);
169 BLI_freelistN(&targets);
173 /* show popup to determine settings */
174 static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
176 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
178 if (ELEM(NULL, ob, ob->pose))
179 return OPERATOR_CANCELLED;
181 /* set default settings from existing/stored settings */
183 bAnimVizSettings *avs = &ob->pose->avs;
186 RNA_int_set(op->ptr, "start_frame", avs->path_sf);
187 RNA_int_set(op->ptr, "end_frame", avs->path_ef);
189 RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
190 RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
193 /* show popup dialog to allow editing of range... */
194 // FIXME: hardcoded dimensions here are just arbitrary
195 return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
198 /* For the object with pose/action: create path curves for selected bones
199 * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
201 static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
203 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
204 Scene *scene = CTX_data_scene(C);
206 if (ELEM(NULL, ob, ob->pose))
207 return OPERATOR_CANCELLED;
209 /* grab baking settings from operator settings */
211 bAnimVizSettings *avs = &ob->pose->avs;
214 avs->path_sf = RNA_int_get(op->ptr, "start_frame");
215 avs->path_ef = RNA_int_get(op->ptr, "end_frame");
217 RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
218 RNA_enum_set(&avs_ptr, "bake_location", RNA_enum_get(op->ptr, "bake_location"));
221 /* set up path data for bones being calculated */
222 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
224 /* verify makes sure that the selected bone has a bone with the appropriate settings */
225 animviz_verify_motionpaths(op->reports, scene, ob, pchan);
229 /* calculate the bones that now have motionpaths... */
230 /* TODO: only make for the selected bones? */
231 ED_pose_recalculate_paths(scene, ob);
233 /* notifiers for updates */
234 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
236 return OPERATOR_FINISHED;
239 void POSE_OT_paths_calculate(wmOperatorType *ot)
242 ot->name = "Calculate Bone Paths";
243 ot->idname = "POSE_OT_paths_calculate";
244 ot->description = "Calculate paths for the selected bones";
247 ot->invoke = pose_calculate_paths_invoke;
248 ot->exec = pose_calculate_paths_exec;
249 ot->poll = ED_operator_posemode_exclusive;
252 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
255 RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start",
256 "First frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
257 RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End",
258 "Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
260 RNA_def_enum(ot->srna, "bake_location", motionpath_bake_location_items, 0,
262 "Which point on the bones is used when calculating paths");
267 static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
269 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
270 Scene *scene = CTX_data_scene(C);
272 if (ELEM(NULL, ob, scene))
273 return OPERATOR_CANCELLED;
275 /* calculate the bones that now have motionpaths... */
276 /* TODO: only make for the selected bones? */
277 ED_pose_recalculate_paths(scene, ob);
279 /* notifiers for updates */
280 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
282 return OPERATOR_FINISHED;
285 void POSE_OT_paths_update(wmOperatorType *ot)
288 ot->name = "Update Bone Paths";
289 ot->idname = "POSE_OT_paths_update";
290 ot->description = "Recalculate paths for bones that already have them";
293 ot->exec = pose_update_paths_exec;
294 ot->poll = ED_operator_posemode_exclusive; /* TODO: this should probably check for active bone and/or existing paths */
297 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
302 /* for the object with pose/action: clear path curves for selected bones only */
303 static void ED_pose_clear_paths(Object *ob)
308 if (ELEM(NULL, ob, ob->pose))
311 /* free the motionpath blocks, but also take note of whether we skipped some... */
312 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
314 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
315 animviz_free_motionpath(pchan->mpath);
323 /* if we didn't skip any, we shouldn't have any paths left */
325 ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
328 /* operator callback for this */
329 static int pose_clear_paths_exec(bContext *C, wmOperator *UNUSED(op))
331 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
333 /* only continue if there's an object */
334 if (ELEM(NULL, ob, ob->pose))
335 return OPERATOR_CANCELLED;
337 /* use the backend function for this */
338 ED_pose_clear_paths(ob);
340 /* notifiers for updates */
341 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
343 return OPERATOR_FINISHED;
346 void POSE_OT_paths_clear(wmOperatorType *ot)
349 ot->name = "Clear Bone Paths";
350 ot->idname = "POSE_OT_paths_clear";
351 ot->description = "Clear path caches for selected bones";
354 ot->exec = pose_clear_paths_exec;
355 ot->poll = ED_operator_posemode_exclusive;
358 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
361 /* ********************************************** */
362 #if 0 /* UNUSED 2.5 */
363 static void pose_copy_menu(Scene *scene)
365 Object *obedit = scene->obedit; // XXX context
368 bPoseChannel *pchan, *pchanact;
372 /* paranoia checks */
373 if (ELEM(NULL, ob, ob->pose)) return;
374 if ((ob == obedit) || (ob->mode & OB_MODE_POSE) == 0) return;
376 pchan = BKE_pose_channel_active(ob);
378 if (pchan == NULL) return;
382 /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changeable,
383 * but for constraints (just add local constraints)
385 if (pose_has_protected_selected(ob, 0)) {
386 i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
388 nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5");
390 nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4");
393 i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
395 nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|Constraints... %x5|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8");
397 nr = pupmenu("Copy Pose Attributes %t|Local Location %x1|Local Rotation %x2|Local Size %x3|%l|Visual Location %x9|Visual Rotation %x10|Visual Size %x11|%l|Constraints (All) %x4|%l|Transform Locks %x6|IK Limits %x7|Bone Shape %x8");
404 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
405 if ((arm->layer & pchan->bone->layer) &&
406 (pchan->bone->flag & BONE_SELECTED) &&
407 (pchan != pchanact) )
410 case 1: /* Local Location */
411 copy_v3_v3(pchan->loc, pchanact->loc);
413 case 2: /* Local Rotation */
414 copy_qt_qt(pchan->quat, pchanact->quat);
415 copy_v3_v3(pchan->eul, pchanact->eul);
417 case 3: /* Local Size */
418 copy_v3_v3(pchan->size, pchanact->size);
420 case 4: /* All Constraints */
422 ListBase tmp_constraints = {NULL, NULL};
424 /* copy constraints to tmpbase and apply 'local' tags before
425 * appending to list of constraints for this channel
427 BKE_constraints_copy(&tmp_constraints, &pchanact->constraints, true);
428 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
431 /* add proxy-local tags */
432 for (con = tmp_constraints.first; con; con = con->next)
433 con->flag |= CONSTRAINT_PROXY_LOCAL;
435 BLI_movelisttolist(&pchan->constraints, &tmp_constraints);
437 /* update flags (need to add here, not just copy) */
438 pchan->constflag |= pchanact->constflag;
441 ob->pose->flag |= POSE_RECALC;
444 case 6: /* Transform Locks */
445 pchan->protectflag = pchanact->protectflag;
447 case 7: /* IK (DOF) settings */
449 pchan->ikflag = pchanact->ikflag;
450 copy_v3_v3(pchan->limitmin, pchanact->limitmin);
451 copy_v3_v3(pchan->limitmax, pchanact->limitmax);
452 copy_v3_v3(pchan->stiffness, pchanact->stiffness);
453 pchan->ikstretch = pchanact->ikstretch;
454 pchan->ikrotweight = pchanact->ikrotweight;
455 pchan->iklinweight = pchanact->iklinweight;
458 case 8: /* Custom Bone Shape */
459 pchan->custom = pchanact->custom;
461 id_us_plus(&pchan->custom->id);
464 case 9: /* Visual Location */
465 BKE_armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
467 case 10: /* Visual Rotation */
469 float delta_mat[4][4];
471 BKE_armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
473 if (pchan->rotmode == ROT_MODE_AXISANGLE) {
476 /* need to convert to quat first (in temp var)... */
477 mat4_to_quat(tmp_quat, delta_mat);
478 quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, tmp_quat);
480 else if (pchan->rotmode == ROT_MODE_QUAT)
481 mat4_to_quat(pchan->quat, delta_mat);
483 mat4_to_eulO(pchan->eul, pchan->rotmode, delta_mat);
486 case 11: /* Visual Size */
488 float delta_mat[4][4], size[4];
490 BKE_armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
491 mat4_to_size(size, delta_mat);
492 copy_v3_v3(pchan->size, size);
498 else { /* constraints, optional (note: max we can have is 24 constraints) */
499 bConstraint *con, *con_back;
500 int const_toggle[24] = {0}; /* XXX, initialize as 0 to quiet errors */
501 ListBase const_copy = {NULL, NULL};
503 BLI_duplicatelist(&const_copy, &(pchanact->constraints));
505 /* build the puplist of constraints */
506 for (con = pchanact->constraints.first, i = 0; con; con = con->next, i++) {
508 // add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
511 // if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
512 // BLI_freelistN(&const_copy);
516 /* now build a new listbase from the options selected */
517 for (i = 0, con = const_copy.first; con; i++) {
518 /* if not selected, free/remove it from the list */
519 if (!const_toggle[i]) {
520 con_back = con->next;
521 BLI_freelinkN(&const_copy, con);
528 /* Copy the temo listbase to the selected posebones */
529 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
530 if ((arm->layer & pchan->bone->layer) &&
531 (pchan->bone->flag & BONE_SELECTED) &&
532 (pchan != pchanact) )
534 ListBase tmp_constraints = {NULL, NULL};
536 /* copy constraints to tmpbase and apply 'local' tags before
537 * appending to list of constraints for this channel
539 BKE_constraints_copy(&tmp_constraints, &const_copy, true);
540 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
541 /* add proxy-local tags */
542 for (con = tmp_constraints.first; con; con = con->next)
543 con->flag |= CONSTRAINT_PROXY_LOCAL;
545 BLI_movelisttolist(&pchan->constraints, &tmp_constraints);
547 /* update flags (need to add here, not just copy) */
548 pchan->constflag |= pchanact->constflag;
551 BLI_freelistN(&const_copy);
552 BKE_pose_update_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
555 ob->pose->flag |= POSE_RECALC;
558 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); // and all its relations
560 BIF_undo_push("Copy Pose Attributes");
565 /* ********************************************** */
567 static int pose_flip_names_exec(bContext *C, wmOperator *UNUSED(op))
569 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
572 /* paranoia checks */
573 if (ELEM(NULL, ob, ob->pose))
574 return OPERATOR_CANCELLED;
577 /* loop through selected bones, auto-naming them */
578 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
580 char name_flip[MAXBONENAME];
581 BKE_deform_flip_side_name(name_flip, pchan->name, true);
582 ED_armature_bone_rename(arm, pchan->name, name_flip);
586 /* since we renamed stuff... */
587 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
589 /* note, notifier might evolve */
590 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
592 return OPERATOR_FINISHED;
595 void POSE_OT_flip_names(wmOperatorType *ot)
598 ot->name = "Flip Names";
599 ot->idname = "POSE_OT_flip_names";
600 ot->description = "Flips (and corrects) the axis suffixes of the the names of selected bones";
603 ot->exec = pose_flip_names_exec;
604 ot->poll = ED_operator_posemode;
607 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
610 /* ------------------ */
612 static int pose_autoside_names_exec(bContext *C, wmOperator *op)
614 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
616 char newname[MAXBONENAME];
617 short axis = RNA_enum_get(op->ptr, "axis");
619 /* paranoia checks */
620 if (ELEM(NULL, ob, ob->pose))
621 return OPERATOR_CANCELLED;
624 /* loop through selected bones, auto-naming them */
625 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
627 BLI_strncpy(newname, pchan->name, sizeof(newname));
628 if (bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]))
629 ED_armature_bone_rename(arm, pchan->name, newname);
633 /* since we renamed stuff... */
634 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
636 /* note, notifier might evolve */
637 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
639 return OPERATOR_FINISHED;
642 void POSE_OT_autoside_names(wmOperatorType *ot)
644 static EnumPropertyItem axis_items[] = {
645 {0, "XAXIS", 0, "X-Axis", "Left/Right"},
646 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
647 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
648 {0, NULL, 0, NULL, NULL}
652 ot->name = "AutoName by Axis";
653 ot->idname = "POSE_OT_autoside_names";
654 ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
657 ot->invoke = WM_menu_invoke;
658 ot->exec = pose_autoside_names_exec;
659 ot->poll = ED_operator_posemode;
662 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
665 ot->prop = RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with");
668 /* ********************************************** */
670 static int pose_bone_rotmode_exec(bContext *C, wmOperator *op)
672 Object *ob = CTX_data_active_object(C);
673 int mode = RNA_enum_get(op->ptr, "type");
675 /* set rotation mode of selected bones */
676 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
678 pchan->rotmode = mode;
682 /* notifiers and updates */
683 DAG_id_tag_update((ID *)ob, OB_RECALC_DATA);
684 WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
686 return OPERATOR_FINISHED;
689 void POSE_OT_rotation_mode_set(wmOperatorType *ot)
692 ot->name = "Set Rotation Mode";
693 ot->idname = "POSE_OT_rotation_mode_set";
694 ot->description = "Set the rotation representation used by selected bones";
697 ot->invoke = WM_menu_invoke;
698 ot->exec = pose_bone_rotmode_exec;
699 ot->poll = ED_operator_posemode;
702 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
705 ot->prop = RNA_def_enum(ot->srna, "type", posebone_rotmode_items, 0, "Rotation Mode", "");
708 /* ********************************************** */
710 /* Show all armature layers */
711 static int pose_armature_layers_showall_poll(bContext *C)
713 /* this single operator can be used in posemode OR editmode for armatures */
714 return ED_operator_posemode(C) || ED_operator_editarmature(C);
717 static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
719 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
720 bArmature *arm = (ob) ? ob->data : NULL;
722 int maxLayers = (RNA_boolean_get(op->ptr, "all")) ? 32 : 16;
723 int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
726 /* sanity checking */
728 return OPERATOR_CANCELLED;
730 /* use RNA to set the layers
731 * although it would be faster to just set directly using bitflags, we still
732 * need to setup a RNA pointer so that we get the "update" callbacks for free...
734 RNA_id_pointer_create(&arm->id, &ptr);
736 for (i = 0; i < maxLayers; i++)
739 RNA_boolean_set_array(&ptr, "layers", layers);
741 /* note, notifier might evolve */
742 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
745 return OPERATOR_FINISHED;
748 void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
751 ot->name = "Show All Layers";
752 ot->idname = "ARMATURE_OT_layers_show_all";
753 ot->description = "Make all armature layers visible";
756 ot->exec = pose_armature_layers_showall_exec;
757 ot->poll = pose_armature_layers_showall_poll;
760 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
763 ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All Layers", "Enable all layers or just the first 16 (top row)");
766 /* ------------------- */
768 /* Present a popup to get the layers that should be used */
769 static int pose_armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
771 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
772 bArmature *arm = (ob) ? ob->data : NULL;
774 int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
776 /* sanity checking */
778 return OPERATOR_CANCELLED;
780 /* get RNA pointer to armature data to use that to retrieve the layers as ints to init the operator */
781 RNA_id_pointer_create((ID *)arm, &ptr);
782 RNA_boolean_get_array(&ptr, "layers", layers);
783 RNA_boolean_set_array(op->ptr, "layers", layers);
785 /* part to sync with other similar operators... */
786 return WM_operator_props_popup(C, op, event);
789 /* Set the visible layers for the active armature (edit and pose modes) */
790 static int pose_armature_layers_exec(bContext *C, wmOperator *op)
792 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
794 int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
796 if (ELEM(NULL, ob, ob->data)) {
797 return OPERATOR_CANCELLED;
800 /* get the values set in the operator properties */
801 RNA_boolean_get_array(op->ptr, "layers", layers);
803 /* get pointer for armature, and write data there... */
804 RNA_id_pointer_create((ID *)ob->data, &ptr);
805 RNA_boolean_set_array(&ptr, "layers", layers);
807 /* note, notifier might evolve */
808 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
810 return OPERATOR_FINISHED;
814 void POSE_OT_armature_layers(wmOperatorType *ot)
817 ot->name = "Change Armature Layers";
818 ot->idname = "POSE_OT_armature_layers";
819 ot->description = "Change the visible armature layers";
822 ot->invoke = pose_armature_layers_invoke;
823 ot->exec = pose_armature_layers_exec;
824 ot->poll = ED_operator_posemode;
827 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
830 RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
833 void ARMATURE_OT_armature_layers(wmOperatorType *ot)
836 ot->name = "Change Armature Layers";
837 ot->idname = "ARMATURE_OT_armature_layers";
838 ot->description = "Change the visible armature layers";
841 ot->invoke = pose_armature_layers_invoke;
842 ot->exec = pose_armature_layers_exec;
843 ot->poll = ED_operator_editarmature;
846 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
849 RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
852 /* ------------------- */
854 /* Present a popup to get the layers that should be used */
855 static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
857 int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
859 /* get layers that are active already */
860 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
864 /* loop over the bits for this pchan's layers, adding layers where they're needed */
865 for (bit = 0; bit < 32; bit++) {
866 if (pchan->bone->layer & (1 << bit))
872 /* copy layers to operator */
873 RNA_boolean_set_array(op->ptr, "layers", layers);
875 /* part to sync with other similar operators... */
876 return WM_operator_props_popup(C, op, event);
879 /* Set the visible layers for the active armature (edit and pose modes) */
880 static int pose_bone_layers_exec(bContext *C, wmOperator *op)
882 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
884 int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
886 if (ob == NULL || ob->data == NULL) {
887 return OPERATOR_CANCELLED;
890 /* get the values set in the operator properties */
891 RNA_boolean_get_array(op->ptr, "layers", layers);
893 /* set layers of pchans based on the values set in the operator props */
894 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
896 /* get pointer for pchan, and write flags this way */
897 RNA_pointer_create((ID *)ob->data, &RNA_Bone, pchan->bone, &ptr);
898 RNA_boolean_set_array(&ptr, "layers", layers);
902 /* note, notifier might evolve */
903 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
905 return OPERATOR_FINISHED;
908 void POSE_OT_bone_layers(wmOperatorType *ot)
911 ot->name = "Change Bone Layers";
912 ot->idname = "POSE_OT_bone_layers";
913 ot->description = "Change the layers that the selected bones belong to";
916 ot->invoke = pose_bone_layers_invoke;
917 ot->exec = pose_bone_layers_exec;
918 ot->poll = ED_operator_posemode_exclusive;
921 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
924 RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
927 /* ------------------- */
929 /* Present a popup to get the layers that should be used */
930 static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
932 int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
934 /* get layers that are active already */
935 CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones)
939 /* loop over the bits for this pchan's layers, adding layers where they're needed */
940 for (bit = 0; bit < 32; bit++) {
941 if (ebone->layer & (1 << bit))
947 /* copy layers to operator */
948 RNA_boolean_set_array(op->ptr, "layers", layers);
950 /* part to sync with other similar operators... */
951 return WM_operator_props_popup(C, op, event);
954 /* Set the visible layers for the active armature (edit and pose modes) */
955 static int armature_bone_layers_exec(bContext *C, wmOperator *op)
957 Object *ob = CTX_data_edit_object(C);
958 bArmature *arm = (ob) ? ob->data : NULL;
960 int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
962 /* get the values set in the operator properties */
963 RNA_boolean_get_array(op->ptr, "layers", layers);
965 /* set layers of pchans based on the values set in the operator props */
966 CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones)
968 /* get pointer for pchan, and write flags this way */
969 RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr);
970 RNA_boolean_set_array(&ptr, "layers", layers);
974 /* note, notifier might evolve */
975 WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
977 return OPERATOR_FINISHED;
980 void ARMATURE_OT_bone_layers(wmOperatorType *ot)
983 ot->name = "Change Bone Layers";
984 ot->idname = "ARMATURE_OT_bone_layers";
985 ot->description = "Change the layers that the selected bones belong to";
988 ot->invoke = armature_bone_layers_invoke;
989 ot->exec = armature_bone_layers_exec;
990 ot->poll = ED_operator_editarmature;
993 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
996 RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
999 /* ********************************************** */
1000 /* Show/Hide Bones */
1002 static int hide_selected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
1004 bArmature *arm = ob->data;
1006 if (arm->layer & bone->layer) {
1007 if (bone->flag & BONE_SELECTED) {
1008 bone->flag |= BONE_HIDDEN_P;
1009 bone->flag &= ~BONE_SELECTED;
1010 if (arm->act_bone == bone)
1011 arm->act_bone = NULL;
1017 static int hide_unselected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
1019 bArmature *arm = ob->data;
1021 if (arm->layer & bone->layer) {
1022 /* hrm... typo here? */
1023 if ((bone->flag & BONE_SELECTED) == 0) {
1024 bone->flag |= BONE_HIDDEN_P;
1025 if (arm->act_bone == bone)
1026 arm->act_bone = NULL;
1032 /* active object is armature in posemode, poll checked */
1033 static int pose_hide_exec(bContext *C, wmOperator *op)
1035 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
1036 bArmature *arm = ob->data;
1038 if (RNA_boolean_get(op->ptr, "unselected"))
1039 bone_looper(ob, arm->bonebase.first, NULL, hide_unselected_pose_bone_cb);
1041 bone_looper(ob, arm->bonebase.first, NULL, hide_selected_pose_bone_cb);
1043 /* note, notifier might evolve */
1044 WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1046 return OPERATOR_FINISHED;
1049 void POSE_OT_hide(wmOperatorType *ot)
1052 ot->name = "Hide Selected";
1053 ot->idname = "POSE_OT_hide";
1054 ot->description = "Tag selected bones to not be visible in Pose Mode";
1057 ot->exec = pose_hide_exec;
1058 ot->poll = ED_operator_posemode;
1061 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1064 RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "");
1067 static int show_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
1069 bArmature *arm = ob->data;
1071 if (arm->layer & bone->layer) {
1072 if (bone->flag & BONE_HIDDEN_P) {
1073 bone->flag &= ~BONE_HIDDEN_P;
1074 bone->flag |= BONE_SELECTED;
1081 /* active object is armature in posemode, poll checked */
1082 static int pose_reveal_exec(bContext *C, wmOperator *UNUSED(op))
1084 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
1085 bArmature *arm = ob->data;
1087 bone_looper(ob, arm->bonebase.first, NULL, show_pose_bone_cb);
1089 /* note, notifier might evolve */
1090 WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1092 return OPERATOR_FINISHED;
1095 void POSE_OT_reveal(wmOperatorType *ot)
1098 ot->name = "Reveal Selected";
1099 ot->idname = "POSE_OT_reveal";
1100 ot->description = "Unhide all bones that have been tagged to be hidden in Pose Mode";
1103 ot->exec = pose_reveal_exec;
1104 ot->poll = ED_operator_posemode;
1107 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1110 /* ********************************************** */
1113 static int pose_flip_quats_exec(bContext *C, wmOperator *UNUSED(op))
1115 Scene *scene = CTX_data_scene(C);
1116 Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
1117 KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
1119 /* loop through all selected pchans, flipping and keying (as needed) */
1120 CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
1122 /* only if bone is using quaternion rotation */
1123 if (pchan->rotmode == ROT_MODE_QUAT) {
1124 /* quaternions have 720 degree range */
1125 negate_v4(pchan->quat);
1127 ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
1132 /* notifiers and updates */
1133 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1134 WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
1136 return OPERATOR_FINISHED;
1139 void POSE_OT_quaternions_flip(wmOperatorType *ot)
1142 ot->name = "Flip Quats";
1143 ot->idname = "POSE_OT_quaternions_flip";
1144 ot->description = "Flip quaternion values to achieve desired rotations, while maintaining the same orientations";
1147 ot->exec = pose_flip_quats_exec;
1148 ot->poll = ED_operator_posemode;
1151 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;