remove unused includes
[blender-staging.git] / source / blender / editors / armature / poseobject.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Ton Roosendaal, Blender Foundation '05, full recode.
24  *                               Joshua Leung
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  * support for animation modes - Reevan McKay
28  */
29
30 #include <stdlib.h>
31 #include <stddef.h>
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_math.h"
37 #include "BLI_blenlib.h"
38 #include "BLI_dynstr.h"
39
40 #include "DNA_anim_types.h"
41 #include "DNA_armature_types.h"
42 #include "DNA_constraint_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_object_types.h"
45
46 #include "BKE_anim.h"
47 #include "BKE_idprop.h"
48 #include "BKE_action.h"
49 #include "BKE_armature.h"
50 #include "BKE_context.h"
51 #include "BKE_constraint.h"
52 #include "BKE_deform.h"
53 #include "BKE_depsgraph.h"
54 #include "BKE_modifier.h"
55 #include "BKE_report.h"
56
57 #include "BIF_gl.h"
58
59 #include "RNA_access.h"
60 #include "RNA_define.h"
61
62 #include "WM_api.h"
63 #include "WM_types.h"
64
65 #include "ED_armature.h"
66 #include "ED_keyframing.h"
67 #include "ED_mesh.h"
68 #include "ED_screen.h"
69
70 #include "UI_interface.h"
71
72 #include "armature_intern.h"
73
74 /* ************* XXX *************** */
75 static int pupmenu(const char *dummy) {return 0;}
76 static void error(const char *dummy) {};
77 static void BIF_undo_push(const char *dummy) {}
78 /* ************* XXX *************** */
79
80 /* This function is used to indicate that a bone is selected and needs keyframes inserted */
81 void set_pose_keys (Object *ob)
82 {
83         bArmature *arm= ob->data;
84         bPoseChannel *chan;
85
86         if (ob->pose){
87                 for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
88                         Bone *bone= chan->bone;
89                         if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
90                                 chan->flag |= POSE_KEY; 
91                         else
92                                 chan->flag &= ~POSE_KEY;
93                 }
94         }
95 }
96
97 /* This function is used to process the necessary updates for */
98 void ED_armature_enter_posemode(bContext *C, Base *base)
99 {
100         Object *ob= base->object;
101         
102         if (ob->id.lib){
103                 error ("Can't pose libdata");
104                 return;
105         }
106         
107         switch (ob->type){
108                 case OB_ARMATURE:
109                         ob->restore_mode = ob->mode;
110                         ob->mode |= OB_MODE_POSE;
111                         
112                         WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_POSE, NULL);
113                         
114                         break;
115                 default:
116                         return;
117         }
118
119         //ED_object_toggle_modes(C, ob->mode);
120 }
121
122 void ED_armature_exit_posemode(bContext *C, Base *base)
123 {
124         if(base) {
125                 Object *ob= base->object;
126                 
127                 ob->restore_mode = ob->mode;
128                 ob->mode &= ~OB_MODE_POSE;
129                 
130                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
131         }       
132 }
133
134 /* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */
135 /* only_selected==1 : the active bone is allowed to be protected */
136 static short pose_has_protected_selected(Object *ob, short only_selected, short warn)
137 {
138         /* check protection */
139         if (ob->proxy) {
140                 bPoseChannel *pchan;
141                 bArmature *arm= ob->data;
142
143                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
144                         if (pchan->bone && (pchan->bone->layer & arm->layer)) {
145                                 if (pchan->bone->layer & arm->layer_protected) {
146                                         if (only_selected && (pchan->bone == arm->act_bone));
147                                         else if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone)
148                                            break;
149                                 }
150                         }
151                 }
152                 if (pchan) {
153                         if (warn) error("Cannot change Proxy protected bones");
154                         return 1;
155                 }
156         }
157         return 0;
158 }
159
160 /* only for real IK, not for auto-IK */
161 int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
162 {
163         bConstraint *con;
164         Bone *bone;
165         
166         /* No need to check if constraint is active (has influence),
167          * since all constraints with CONSTRAINT_IK_AUTO are active */
168         for(con= pchan->constraints.first; con; con= con->next) {
169                 if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
170                         bKinematicConstraint *data= con->data;
171                         if((data->flag & CONSTRAINT_IK_AUTO)==0)
172                                 return 1;
173                 }
174         }
175         for(bone= pchan->bone->childbase.first; bone; bone= bone->next) {
176                 pchan= get_pose_channel(ob->pose, bone->name);
177                 if(pchan && ED_pose_channel_in_IK_chain(ob, pchan))
178                         return 1;
179         }
180         return 0;
181 }
182
183 /* ********************************************** */
184 /* Motion Paths */
185
186 /* For the object with pose/action: update paths for those that have got them
187  * This should selectively update paths that exist...
188  *
189  * To be called from various tools that do incremental updates 
190  */
191 void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
192 {
193         ListBase targets = {NULL, NULL};
194         
195         /* set flag to force recalc, then grab the relevant bones to target */
196         ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
197         animviz_get_object_motionpaths(ob, &targets);
198         
199         /* recalculate paths, then free */
200         animviz_calc_motionpaths(scene, &targets);
201         BLI_freelistN(&targets);
202 }
203
204 /* For the object with pose/action: create path curves for selected bones 
205  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
206  */
207 static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
208 {
209         ScrArea *sa= CTX_wm_area(C);
210         Scene *scene= CTX_data_scene(C);
211         Object *ob;
212         
213         /* since this call may also be used from the buttons window, we need to check for where to get the object */
214         if (sa->spacetype == SPACE_BUTS) 
215                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
216         else
217                 ob= CTX_data_active_object(C);
218                 
219         if (ELEM(NULL, ob, ob->pose))
220                 return OPERATOR_CANCELLED;
221         
222         /* set up path data for bones being calculated */
223         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
224         {
225                 /* verify makes sure that the selected bone has a bone with the appropriate settings */
226                 animviz_verify_motionpaths(scene, ob, pchan);
227         }
228         CTX_DATA_END;
229         
230         /* calculate the bones that now have motionpaths... */
231         // TODO: only make for the selected bones?
232         ED_pose_recalculate_paths(C, scene, ob);
233         
234         /* notifiers for updates */
235         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
236         
237         return OPERATOR_FINISHED; 
238 }
239
240 void POSE_OT_paths_calculate (wmOperatorType *ot)
241 {
242         /* identifiers */
243         ot->name= "Calculate Bone Paths";
244         ot->idname= "POSE_OT_paths_calculate";
245         ot->description= "Calculate paths for the selected bones";
246         
247         /* api callbacks */
248         ot->exec= pose_calculate_paths_exec;
249         ot->poll= ED_operator_posemode;
250         
251         /* flags */
252         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
253 }
254
255 /* --------- */
256
257 /* for the object with pose/action: clear path curves for selected bones only */
258 void ED_pose_clear_paths(Object *ob)
259 {
260         bPoseChannel *pchan;
261         short skipped = 0;
262         
263         if ELEM(NULL, ob, ob->pose)
264                 return;
265         
266         /* free the motionpath blocks, but also take note of whether we skipped some... */
267         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
268                 if (pchan->mpath) {
269                         if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
270                                 animviz_free_motionpath(pchan->mpath);
271                                 pchan->mpath= NULL;
272                         }
273                         else 
274                                 skipped = 1;
275                 }
276         }
277         
278         /* if we didn't skip any, we shouldn't have any paths left */
279         if (skipped == 0)
280                 ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
281 }
282
283 /* operator callback for this */
284 static int pose_clear_paths_exec (bContext *C, wmOperator *op)
285 {
286         ScrArea *sa= CTX_wm_area(C);
287         Object *ob;
288         
289         /* since this call may also be used from the buttons window, we need to check for where to get the object */
290         if (sa->spacetype == SPACE_BUTS) 
291                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
292         else
293                 ob= CTX_data_active_object(C);
294                 
295         /* only continue if there's an object */
296         if ELEM(NULL, ob, ob->pose)
297                 return OPERATOR_CANCELLED;
298         
299         /* use the backend function for this */
300         ED_pose_clear_paths(ob);
301         
302         /* notifiers for updates */
303         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
304         
305         return OPERATOR_FINISHED; 
306 }
307
308 void POSE_OT_paths_clear (wmOperatorType *ot)
309 {
310         /* identifiers */
311         ot->name= "Clear Bone Paths";
312         ot->idname= "POSE_OT_paths_clear";
313         ot->description= "Clear path caches for selected bones";
314         
315         /* api callbacks */
316         ot->exec= pose_clear_paths_exec;
317         ot->poll= ED_operator_posemode;
318         
319         /* flags */
320         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
321 }
322
323 /* ******************* Select Constraint Target Operator ************* */
324
325 static int pose_select_constraint_target_exec(bContext *C, wmOperator *op)
326 {
327         Object *ob= CTX_data_active_object(C);
328         bArmature *arm= ob->data;
329         bConstraint *con;
330         int found= 0;
331         
332         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
333         {
334                 if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) {
335                         for (con= pchan->constraints.first; con; con= con->next) {
336                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
337                                 ListBase targets = {NULL, NULL};
338                                 bConstraintTarget *ct;
339                                 
340                                 if (cti && cti->get_constraint_targets) {
341                                         cti->get_constraint_targets(con, &targets);
342                                         
343                                         for (ct= targets.first; ct; ct= ct->next) {
344                                                 if ((ct->tar == ob) && (ct->subtarget[0])) {
345                                                         bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
346                                                         if((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) {
347                                                                 pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
348                                                                 found= 1;
349                                                         }
350                                                 }
351                                         }
352                                         
353                                         if (cti->flush_constraint_targets)
354                                                 cti->flush_constraint_targets(con, &targets, 1);
355                                 }
356                         }
357                 }
358         }
359         CTX_DATA_END;
360
361         if (!found)
362                 return OPERATOR_CANCELLED;
363
364         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
365
366         return OPERATOR_FINISHED;
367 }
368
369 void POSE_OT_select_constraint_target(wmOperatorType *ot)
370 {
371         /* identifiers */
372         ot->name= "Select Constraint Target";
373         ot->idname= "POSE_OT_select_constraint_target";
374         
375         /* api callbacks */
376         ot->exec= pose_select_constraint_target_exec;
377         ot->poll= ED_operator_posemode;
378         
379         /* flags */
380         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
381 }
382
383 /* ******************* select hierarchy operator ************* */
384
385 static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
386 {
387         Object *ob= CTX_data_active_object(C);
388         bArmature *arm= ob->data;
389         Bone *curbone, *pabone, *chbone;
390         int direction = RNA_enum_get(op->ptr, "direction");
391         int add_to_sel = RNA_boolean_get(op->ptr, "extend");
392         int found= 0;
393         
394         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
395         {
396                 curbone= pchan->bone;
397                 
398                 if ((curbone->flag & BONE_UNSELECTABLE)==0) {
399                         if (curbone == arm->act_bone) {
400                                 if (direction == BONE_SELECT_PARENT) {
401                                         if (pchan->parent == NULL) continue;
402                                         else pabone= pchan->parent->bone;
403                                         
404                                         if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_P)) {
405                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
406                                                 pabone->flag |= BONE_SELECTED;
407                                                 arm->act_bone= pabone;
408                                                 
409                                                 found= 1;
410                                                 break;
411                                         }
412                                 } 
413                                 else { /* direction == BONE_SELECT_CHILD */
414                                         if (pchan->child == NULL) continue;
415                                         else chbone = pchan->child->bone;
416                                         
417                                         if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_P)) {
418                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
419                                                 chbone->flag |= BONE_SELECTED;
420                                                 arm->act_bone= chbone;
421                                                 
422                                                 found= 1;
423                                                 break;
424                                         }
425                                 }
426                         }
427                 }
428         }
429         CTX_DATA_END;
430
431         if (found == 0)
432                 return OPERATOR_CANCELLED;
433
434         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
435
436         return OPERATOR_FINISHED;
437 }
438
439 void POSE_OT_select_hierarchy(wmOperatorType *ot)
440 {
441         static EnumPropertyItem direction_items[]= {
442         {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
443         {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
444         {0, NULL, 0, NULL, NULL}
445         };
446         
447         /* identifiers */
448         ot->name= "Select Hierarchy";
449         ot->idname= "POSE_OT_select_hierarchy";
450         
451         /* api callbacks */
452         ot->exec= pose_select_hierarchy_exec;
453         ot->poll= ED_operator_posemode;
454         
455         /* flags */
456         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
457         
458         /* props */
459         ot->prop= RNA_def_enum(ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
460         RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
461         
462 }
463
464 /* ******************* select grouped operator ************* */
465
466 static short pose_select_same_group (bContext *C, Object *ob, short extend)
467 {
468         bArmature *arm= (ob)? ob->data : NULL;
469         bPose *pose= (ob)? ob->pose : NULL;
470         char *group_flags;
471         int numGroups = 0;
472         short changed=0, tagged=0;
473         
474         /* sanity checks */
475         if (ELEM3(NULL, ob, pose, arm))
476                 return 0;
477                 
478         /* count the number of groups */
479         numGroups= BLI_countlist(&pose->agroups);
480         if (numGroups == 0)
481                 return 0;
482                 
483         /* alloc a small array to keep track of the groups to use 
484          *      - each cell stores on/off state for whether group should be used
485          *      - size is numGroups + 1, since index=0 is used for no-group
486          */
487         group_flags= MEM_callocN(numGroups+1, "pose_select_same_group");
488         
489         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
490         {
491                 /* keep track of group as group to use later? */
492                 if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) {
493                         group_flags[pchan->agrp_index] = 1;
494                         tagged= 1;
495                 }
496                 
497                 /* deselect all bones before selecting new ones? */
498                 if ((extend == 0) && (pchan->bone->flag & BONE_UNSELECTABLE)==0)
499                         pchan->bone->flag &= ~BONE_SELECTED;
500         }
501         CTX_DATA_END;
502         
503         /* small optimisation: only loop through bones a second time if there are any groups tagged */
504         if (tagged) {
505                 /* only if group matches (and is not selected or current bone) */
506                 CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
507                 {
508                         if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) {
509                                 /* check if the group used by this bone is counted */
510                                 if (group_flags[pchan->agrp_index]) {
511                                         pchan->bone->flag |= BONE_SELECTED;
512                                         changed= 1;
513                                 }
514                         }
515                 }
516                 CTX_DATA_END;
517         }
518         
519         /* free temp info */
520         MEM_freeN(group_flags);
521         
522         return changed;
523 }
524
525 static short pose_select_same_layer (bContext *C, Object *ob, short extend)
526 {
527         bPose *pose= (ob)? ob->pose : NULL;
528         bArmature *arm= (ob)? ob->data : NULL;
529         short changed= 0;
530         int layers= 0;
531         
532         if (ELEM3(NULL, ob, pose, arm))
533                 return 0;
534         
535         /* figure out what bones are selected */
536         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
537         {
538                 /* keep track of layers to use later? */
539                 if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone))
540                         layers |= pchan->bone->layer;
541                         
542                 /* deselect all bones before selecting new ones? */
543                 if ((extend == 0) && (pchan->bone->flag & BONE_UNSELECTABLE)==0)
544                         pchan->bone->flag &= ~BONE_SELECTED;
545         }
546         CTX_DATA_END;
547         if (layers == 0) 
548                 return 0;
549                 
550         /* select bones that are on same layers as layers flag */
551         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
552         {
553                 /* if bone is on a suitable layer, and the bone can have its selection changed, select it */
554                 if ((layers & pchan->bone->layer) && (pchan->bone->flag & BONE_UNSELECTABLE)==0) {
555                         pchan->bone->flag |= BONE_SELECTED;
556                         changed= 1;
557                 }
558         }
559         CTX_DATA_END;
560         
561         return changed;
562 }
563
564
565 static int pose_select_grouped_exec (bContext *C, wmOperator *op)
566 {
567         Object *ob= CTX_data_active_object(C);
568         short extend= RNA_boolean_get(op->ptr, "extend");
569         short changed = 0;
570         
571         /* sanity check */
572         if (ELEM(NULL, ob, ob->pose))
573                 return OPERATOR_CANCELLED;
574                 
575         /* selection types 
576          * NOTE: for the order of these, see the enum in POSE_OT_select_grouped()
577          */
578         switch (RNA_enum_get(op->ptr, "type")) {
579                 case 1: /* group */
580                         changed= pose_select_same_group(C, ob, extend);
581                         break;
582                 default: /* layer */
583                         changed= pose_select_same_layer(C, ob, extend);
584                         break;
585         }
586         
587         /* notifiers for updates */
588         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
589         
590         /* report done status */
591         if (changed)
592                 return OPERATOR_FINISHED;
593         else
594                 return OPERATOR_CANCELLED;
595 }
596
597 void POSE_OT_select_grouped (wmOperatorType *ot)
598 {
599         static EnumPropertyItem prop_select_grouped_types[] = {
600                 {0, "LAYER", 0, "Layer", "Shared layers"},
601                 {1, "GROUP", 0, "Group", "Shared group"},
602                 {0, NULL, 0, NULL, NULL}
603         };
604
605         /* identifiers */
606         ot->name= "Select Grouped";
607         ot->description = "Select all visible bones grouped by various properties";
608         ot->idname= "POSE_OT_select_grouped";
609         
610         /* api callbacks */
611         ot->invoke= WM_menu_invoke;
612         ot->exec= pose_select_grouped_exec;
613         ot->poll= ED_operator_posemode;
614         
615         /* flags */
616         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
617         
618         /* properties */
619         RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
620         ot->prop= RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
621 }
622
623 /* ********************************************** */
624
625 void pose_copy_menu(Scene *scene)
626 {
627         Object *obedit= scene->obedit; // XXX context
628         Object *ob= OBACT;
629         bArmature *arm= ob->data;
630         bPoseChannel *pchan, *pchanact;
631         short nr=0;
632         int i=0;
633         
634         /* paranoia checks */
635         if (ELEM(NULL, ob, ob->pose)) return;
636         if ((ob==obedit) || (ob->mode & OB_MODE_POSE)==0) return;
637         
638         pchan= get_active_posechannel(ob);
639         
640         if (pchan==NULL) return;
641         pchanact= pchan;
642         
643         /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable, 
644          * but for constraints (just add local constraints)
645          */
646         if (pose_has_protected_selected(ob, 1, 0)) {
647                 i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
648                 if (i < 25)
649                         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");
650                 else
651                         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");
652         }
653         else {
654                 i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
655                 if (i < 25)
656                         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");
657                 else
658                         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");
659         }
660         
661         if (nr <= 0) 
662                 return;
663         
664         if (nr != 5)  {
665                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
666                         if ( (arm->layer & pchan->bone->layer) &&
667                                  (pchan->bone->flag & BONE_SELECTED) &&
668                                  (pchan != pchanact) ) 
669                         {
670                                 switch (nr) {
671                                         case 1: /* Local Location */
672                                                 VECCOPY(pchan->loc, pchanact->loc);
673                                                 break;
674                                         case 2: /* Local Rotation */
675                                                 QUATCOPY(pchan->quat, pchanact->quat);
676                                                 VECCOPY(pchan->eul, pchanact->eul);
677                                                 break;
678                                         case 3: /* Local Size */
679                                                 VECCOPY(pchan->size, pchanact->size);
680                                                 break;
681                                         case 4: /* All Constraints */
682                                         {
683                                                 ListBase tmp_constraints = {NULL, NULL};
684                                                 
685                                                 /* copy constraints to tmpbase and apply 'local' tags before 
686                                                  * appending to list of constraints for this channel
687                                                  */
688                                                 copy_constraints(&tmp_constraints, &pchanact->constraints, TRUE);
689                                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
690                                                         bConstraint *con;
691                                                         
692                                                         /* add proxy-local tags */
693                                                         for (con= tmp_constraints.first; con; con= con->next)
694                                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
695                                                 }
696                                                 addlisttolist(&pchan->constraints, &tmp_constraints);
697                                                 
698                                                 /* update flags (need to add here, not just copy) */
699                                                 pchan->constflag |= pchanact->constflag;
700                                                 
701                                                 if (ob->pose)
702                                                         ob->pose->flag |= POSE_RECALC;
703                                         }
704                                                 break;
705                                         case 6: /* Transform Locks */
706                                                 pchan->protectflag = pchanact->protectflag;
707                                                 break;
708                                         case 7: /* IK (DOF) settings */
709                                         {
710                                                 pchan->ikflag = pchanact->ikflag;
711                                                 VECCOPY(pchan->limitmin, pchanact->limitmin);
712                                                 VECCOPY(pchan->limitmax, pchanact->limitmax);
713                                                 VECCOPY(pchan->stiffness, pchanact->stiffness);
714                                                 pchan->ikstretch= pchanact->ikstretch;
715                                                 pchan->ikrotweight= pchanact->ikrotweight;
716                                                 pchan->iklinweight= pchanact->iklinweight;
717                                         }
718                                                 break;
719                                         case 8: /* Custom Bone Shape */
720                                                 pchan->custom = pchanact->custom;
721                                                 break;
722                                         case 9: /* Visual Location */
723                                                 armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
724                                                 break;
725                                         case 10: /* Visual Rotation */
726                                         {
727                                                 float delta_mat[4][4];
728                                                 
729                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
730                                                 
731                                                 if (pchan->rotmode == ROT_MODE_AXISANGLE) {
732                                                         float tmp_quat[4];
733                                                         
734                                                         /* need to convert to quat first (in temp var)... */
735                                                         mat4_to_quat( tmp_quat,delta_mat);
736                                                         quat_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,tmp_quat);
737                                                 }
738                                                 else if (pchan->rotmode == ROT_MODE_QUAT)
739                                                         mat4_to_quat( pchan->quat,delta_mat);
740                                                 else
741                                                         mat4_to_eulO( pchan->eul, pchan->rotmode,delta_mat);
742                                         }
743                                                 break;
744                                         case 11: /* Visual Size */
745                                         {
746                                                 float delta_mat[4][4], size[4];
747                                                 
748                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
749                                                 mat4_to_size( size,delta_mat);
750                                                 VECCOPY(pchan->size, size);
751                                         }
752                                 }
753                         }
754                 }
755         } 
756         else { /* constraints, optional (note: max we can have is 24 constraints) */
757                 bConstraint *con, *con_back;
758                 int const_toggle[24];
759                 ListBase const_copy = {NULL, NULL};
760                 
761                 BLI_duplicatelist(&const_copy, &(pchanact->constraints));
762                 
763                 /* build the puplist of constraints */
764                 for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){
765                         const_toggle[i]= 1;
766 //                      add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
767                 }
768                 
769 //              if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
770 //                      BLI_freelistN(&const_copy);
771 //                      return;
772 //              }
773                 
774                 /* now build a new listbase from the options selected */
775                 for (i=0, con=const_copy.first; con; i++) {
776                         /* if not selected, free/remove it from the list */
777                         if (!const_toggle[i]) {
778                                 con_back= con->next;
779                                 BLI_freelinkN(&const_copy, con);
780                                 con= con_back;
781                         } 
782                         else
783                                 con= con->next;
784                 }
785                 
786                 /* Copy the temo listbase to the selected posebones */
787                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
788                         if ( (arm->layer & pchan->bone->layer) &&
789                                  (pchan->bone->flag & BONE_SELECTED) &&
790                                  (pchan!=pchanact) ) 
791                         {
792                                 ListBase tmp_constraints = {NULL, NULL};
793                                 
794                                 /* copy constraints to tmpbase and apply 'local' tags before 
795                                  * appending to list of constraints for this channel
796                                  */
797                                 copy_constraints(&tmp_constraints, &const_copy, TRUE);
798                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
799                                         bConstraint *con;
800                                         
801                                         /* add proxy-local tags */
802                                         for (con= tmp_constraints.first; con; con= con->next)
803                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
804                                 }
805                                 addlisttolist(&pchan->constraints, &tmp_constraints);
806                                 
807                                 /* update flags (need to add here, not just copy) */
808                                 pchan->constflag |= pchanact->constflag;
809                         }
810                 }
811                 BLI_freelistN(&const_copy);
812                 update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
813                 
814                 if (ob->pose)
815                         ob->pose->flag |= POSE_RECALC;
816         }
817         
818         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);   // and all its relations
819         
820         BIF_undo_push("Copy Pose Attributes");
821         
822 }
823
824 /* ******************** copy/paste pose ********************** */
825
826 /* Global copy/paste buffer for pose - cleared on start/end session + before every copy operation */
827 static bPose *g_posebuf = NULL;
828
829 void free_posebuf(void) 
830 {
831         if (g_posebuf) {
832                 bPoseChannel *pchan;
833                 
834                 for (pchan= g_posebuf->chanbase.first; pchan; pchan= pchan->next) {
835                         if(pchan->prop) {
836                                 IDP_FreeProperty(pchan->prop);
837                                 MEM_freeN(pchan->prop);
838                         }
839                 }
840                 
841                 /* was copied without constraints */
842                 BLI_freelistN(&g_posebuf->chanbase);
843                 MEM_freeN(g_posebuf);
844         }
845         
846         g_posebuf=NULL;
847 }
848
849 /* ---- */
850
851 static int pose_copy_exec (bContext *C, wmOperator *op)
852 {
853         Object *ob= CTX_data_active_object(C);
854         
855         /* sanity checking */
856         if ELEM(NULL, ob, ob->pose) {
857                 BKE_report(op->reports, RPT_ERROR, "No Pose to Copy");
858                 return OPERATOR_CANCELLED;
859         }
860
861         /* free existing pose buffer */
862         free_posebuf();
863         
864         /* sets chan->flag to POSE_KEY if bone selected, then copy those bones to the buffer */
865         set_pose_keys(ob);  
866         copy_pose(&g_posebuf, ob->pose, 0);
867         
868         
869         return OPERATOR_FINISHED;
870 }
871
872 void POSE_OT_copy (wmOperatorType *ot) 
873 {
874         /* identifiers */
875         ot->name= "Copy Pose";
876         ot->idname= "POSE_OT_copy";
877         ot->description= "Copies the current pose of the selected bones to copy/paste buffer";
878         
879         /* api callbacks */
880         ot->exec= pose_copy_exec;
881         ot->poll= ED_operator_posemode;
882         
883         /* flag */
884         ot->flag= OPTYPE_REGISTER;
885 }
886
887 /* ---- */
888
889 static int pose_paste_exec (bContext *C, wmOperator *op)
890 {
891         Scene *scene= CTX_data_scene(C);
892         Object *ob= CTX_data_active_object(C);
893         bPoseChannel *chan, *pchan;
894         int flip= RNA_boolean_get(op->ptr, "flipped");
895         
896         /* sanity checks */
897         if ELEM(NULL, ob, ob->pose)
898                 return OPERATOR_CANCELLED;
899
900         if (g_posebuf == NULL) {
901                 BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
902                 return OPERATOR_CANCELLED;
903         }
904         
905         /* Safely merge all of the channels in the buffer pose into any existing pose */
906         for (chan= g_posebuf->chanbase.first; chan; chan=chan->next) {
907                 if (chan->flag & POSE_KEY) {
908                         /* get the name - if flipping, we must flip this first */
909                         char name[32];
910                         if (flip)
911                                 flip_side_name(name, chan->name, 0);            /* 0 = don't strip off number extensions */
912                         else
913                                 BLI_strncpy(name, chan->name, sizeof(name));
914
915                         /* only copy when channel exists, poses are not meant to add random channels to anymore */
916                         pchan= get_pose_channel(ob->pose, name);
917                         
918                         if (pchan) {
919                                 /* only loc rot size 
920                                  *      - only copies transform info for the pose 
921                                  */
922                                 VECCOPY(pchan->loc, chan->loc);
923                                 VECCOPY(pchan->size, chan->size);
924                                 pchan->flag= chan->flag;
925                                 
926                                 /* check if rotation modes are compatible (i.e. do they need any conversions) */
927                                 if (pchan->rotmode == chan->rotmode) {
928                                         /* copy the type of rotation in use */
929                                         if (pchan->rotmode > 0) {
930                                                 VECCOPY(pchan->eul, chan->eul);
931                                         }
932                                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
933                                                 VECCOPY(pchan->rotAxis, chan->rotAxis);
934                                                 pchan->rotAngle = chan->rotAngle;
935                                         }
936                                         else {
937                                                 QUATCOPY(pchan->quat, chan->quat);
938                                         }
939                                 }
940                                 else if (pchan->rotmode > 0) {
941                                         /* quat/axis-angle to euler */
942                                         if (chan->rotmode == ROT_MODE_AXISANGLE)
943                                                 axis_angle_to_eulO( pchan->eul, pchan->rotmode,chan->rotAxis, chan->rotAngle);
944                                         else
945                                                 quat_to_eulO( pchan->eul, pchan->rotmode,chan->quat);
946                                 }
947                                 else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
948                                         /* quat/euler to axis angle */
949                                         if (chan->rotmode > 0)
950                                                 eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->eul, chan->rotmode);
951                                         else    
952                                                 quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, chan->quat);
953                                 }
954                                 else {
955                                         /* euler/axis-angle to quat */
956                                         if (chan->rotmode > 0)
957                                                 eulO_to_quat(pchan->quat, chan->eul, chan->rotmode);
958                                         else
959                                                 axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle);
960                                 }
961                                 
962                                 /* paste flipped pose? */
963                                 if (flip) {
964                                         pchan->loc[0]*= -1;
965                                         
966                                         /* has to be done as eulers... */
967                                         if (pchan->rotmode > 0) {
968                                                 pchan->eul[1] *= -1;
969                                                 pchan->eul[2] *= -1;
970                                         }
971                                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
972                                                 float eul[3];
973                                                 
974                                                 axis_angle_to_eulO(eul, EULER_ORDER_DEFAULT, pchan->rotAxis, pchan->rotAngle);
975                                                 eul[1]*= -1;
976                                                 eul[2]*= -1;
977                                                 eulO_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, eul, EULER_ORDER_DEFAULT);
978                                         }
979                                         else {
980                                                 float eul[3];
981                                                 
982                                                 quat_to_eul(eul, pchan->quat);
983                                                 eul[1]*= -1;
984                                                 eul[2]*= -1;
985                                                 eul_to_quat(pchan->quat, eul);
986                                         }
987                                 }
988                                 
989                                 /* ID properties 
990                                  *      - only free the existing properties if the channel we're copying from has them
991                                  *        NOTE: this means that if the pose depends on some pchan property, the pose may not be ok,
992                                  *                  but this is better than loosing all the setting you've painstakingly added...
993                                  */
994                                 if (chan->prop) {
995                                         /* free the old properties since we want to replace them now */
996                                         if (pchan->prop) {
997                                                 IDP_FreeProperty(pchan->prop);
998                                                 MEM_freeN(pchan->prop);
999                                                 pchan->prop= NULL;
1000                                         }
1001                                         
1002                                         /* now copy over the new copy of the properties */
1003                                         pchan->prop= IDP_CopyProperty(chan->prop);      
1004                                 }
1005                                 
1006                                 /* keyframing tagging */
1007                                 if (autokeyframe_cfra_can_key(scene, &ob->id)) {
1008                                         ListBase dsources = {NULL, NULL};
1009                                         KeyingSet *ks = NULL;
1010                                         
1011                                         /* get KeyingSet to use 
1012                                          *      - use the active KeyingSet if defined (and user wants to use it for all autokeying), 
1013                                          *        or otherwise key transforms only
1014                                          */
1015                                         if (IS_AUTOKEY_FLAG(ONLYKEYINGSET) && (scene->active_keyingset))
1016                                                 ks = ANIM_scene_get_active_keyingset(scene);
1017                                         else 
1018                                                 ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
1019                                         
1020                                         /* now insert the keyframe(s) using the Keying Set
1021                                          *      1) add datasource override for the PoseChannel
1022                                          *      2) insert keyframes
1023                                          *      3) free the extra info 
1024                                          */
1025                                         ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan); 
1026                                         ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
1027                                         BLI_freelistN(&dsources);
1028                                         
1029                                         /* clear any unkeyed tags */
1030                                         if (chan->bone)
1031                                                 chan->bone->flag &= ~BONE_UNKEYED;
1032                                 }
1033                                 else {
1034                                         /* add unkeyed tags */
1035                                         if (chan->bone)
1036                                                 chan->bone->flag |= BONE_UNKEYED;
1037                                 }
1038                         }
1039                 }
1040         }
1041         
1042         /* Update event for pose and deformation children */
1043         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1044                 
1045         /* notifiers for updates */
1046         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1047
1048         return OPERATOR_FINISHED;
1049 }
1050
1051 void POSE_OT_paste (wmOperatorType *ot)
1052 {
1053         /* identifiers */
1054         ot->name= "Paste Pose";
1055         ot->idname= "POSE_OT_paste";
1056         ot->description= "Pastes the stored pose on to the current pose";
1057         
1058         /* api callbacks */
1059         ot->exec= pose_paste_exec;
1060         ot->poll= ED_operator_posemode;
1061         
1062         /* flag */
1063         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1064         
1065         /* properties */
1066         RNA_def_boolean(ot->srna, "flipped", 0, "Flipped on X-Axis", "");
1067 }
1068
1069 /* ********************************************** */
1070
1071
1072 static int pose_group_add_exec (bContext *C, wmOperator *op)
1073 {
1074         ScrArea *sa= CTX_wm_area(C);
1075         Object *ob;
1076         
1077         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1078         if (sa->spacetype == SPACE_BUTS) 
1079                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1080         else
1081                 ob= CTX_data_active_object(C);
1082                 
1083         /* only continue if there's an object */
1084         if (ob == NULL)
1085                 return OPERATOR_CANCELLED;
1086         
1087         /* for now, just call the API function for this */
1088         pose_add_group(ob);
1089         
1090         /* notifiers for updates */
1091         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1092         
1093         return OPERATOR_FINISHED;
1094 }
1095
1096 void POSE_OT_group_add (wmOperatorType *ot)
1097 {
1098         /* identifiers */
1099         ot->name= "Add Bone Group";
1100         ot->idname= "POSE_OT_group_add";
1101         ot->description= "Add a new bone group";
1102         
1103         /* api callbacks */
1104         ot->exec= pose_group_add_exec;
1105         ot->poll= ED_operator_posemode;
1106         
1107         /* flags */
1108         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1109 }
1110
1111
1112 static int pose_group_remove_exec (bContext *C, wmOperator *op)
1113 {
1114         ScrArea *sa= CTX_wm_area(C);
1115         Object *ob;
1116         
1117         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1118         if (sa->spacetype == SPACE_BUTS) 
1119                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1120         else
1121                 ob= CTX_data_active_object(C);
1122         
1123         /* only continue if there's an object */
1124         if (ob == NULL)
1125                 return OPERATOR_CANCELLED;
1126         
1127         /* for now, just call the API function for this */
1128         pose_remove_group(ob);
1129         
1130         /* notifiers for updates */
1131         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1132         
1133         return OPERATOR_FINISHED;
1134 }
1135
1136 void POSE_OT_group_remove (wmOperatorType *ot)
1137 {
1138         /* identifiers */
1139         ot->name= "Remove Bone Group";
1140         ot->idname= "POSE_OT_group_remove";
1141         ot->description= "Removes the active bone group";
1142         
1143         /* api callbacks */
1144         ot->exec= pose_group_remove_exec;
1145         ot->poll= ED_operator_posemode;
1146         
1147         /* flags */
1148         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1149 }
1150
1151 /* ------------ */
1152
1153 /* invoke callback which presents a list of bone-groups for the user to choose from */
1154 static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1155 {
1156         ScrArea *sa= CTX_wm_area(C);
1157         Object *ob;
1158         bPose *pose;
1159         
1160         uiPopupMenu *pup;
1161         uiLayout *layout;
1162         bActionGroup *grp;
1163         int i;
1164         
1165         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1166         if (sa->spacetype == SPACE_BUTS) 
1167                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1168         else
1169                 ob= CTX_data_active_object(C);
1170         
1171         /* only continue if there's an object, and a pose there too */
1172         if (ELEM(NULL, ob, ob->pose)) 
1173                 return OPERATOR_CANCELLED;
1174         pose= ob->pose;
1175         
1176         /* if there's no active group (or active is invalid), create a new menu to find it */
1177         if (pose->active_group <= 0) {
1178                 /* create a new menu, and start populating it with group names */
1179                 pup= uiPupMenuBegin(C, op->type->name, 0);
1180                 layout= uiPupMenuLayout(pup);
1181                 
1182                 /* special entry - allow to create new group, then use that 
1183                  *      (not to be used for removing though)
1184                  */
1185                 if (strstr(op->idname, "assign")) {
1186                         uiItemIntO(layout, "New Group", 0, op->idname, "type", 0);
1187                         uiItemS(layout);
1188                 }
1189                 
1190                 /* add entries for each group */
1191                 for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++)
1192                         uiItemIntO(layout, grp->name, 0, op->idname, "type", i);
1193                         
1194                 /* finish building the menu, and process it (should result in calling self again) */
1195                 uiPupMenuEnd(C, pup);
1196                 
1197                 return OPERATOR_CANCELLED;
1198         }
1199         else {
1200                 /* just use the active group index, and call the exec callback for the calling operator */
1201                 RNA_int_set(op->ptr, "type", pose->active_group);
1202                 return op->type->exec(C, op);
1203         }
1204 }
1205
1206 /* Assign selected pchans to the bone group that the user selects */
1207 static int pose_group_assign_exec (bContext *C, wmOperator *op)
1208 {
1209         ScrArea *sa= CTX_wm_area(C);
1210         Object *ob;
1211         bArmature *arm;
1212         bPose *pose;
1213         short done= 0;
1214         
1215         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1216         if (sa->spacetype == SPACE_BUTS) 
1217                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1218         else
1219                 ob= CTX_data_active_object(C);
1220         
1221         /* only continue if there's an object, and a pose there too */
1222         if (ELEM(NULL, ob, ob->pose))
1223                 return OPERATOR_CANCELLED;
1224         arm= ob->data;
1225         pose= ob->pose;
1226         
1227         /* set the active group number to the one from operator props 
1228          *      - if 0 after this, make a new group...
1229          */
1230         pose->active_group= RNA_int_get(op->ptr, "type");
1231         if (pose->active_group == 0)
1232                 pose_add_group(ob);
1233         
1234         /* add selected bones to group then */
1235         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1236         {
1237                 pchan->agrp_index= pose->active_group;
1238                 done= 1;
1239         }
1240         CTX_DATA_END;
1241
1242         /* notifiers for updates */
1243         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1244         
1245         /* report done status */
1246         if (done)
1247                 return OPERATOR_FINISHED;
1248         else
1249                 return OPERATOR_CANCELLED;
1250 }
1251
1252 void POSE_OT_group_assign (wmOperatorType *ot)
1253 {
1254         /* identifiers */
1255         ot->name= "Add Selected to Bone Group";
1256         ot->idname= "POSE_OT_group_assign";
1257         ot->description= "Add selected bones to the chosen bone group";
1258         
1259         /* api callbacks */
1260         ot->invoke= pose_groups_menu_invoke;
1261         ot->exec= pose_group_assign_exec;
1262         ot->poll= ED_operator_posemode;
1263         
1264         /* flags */
1265         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1266         
1267         /* properties */
1268         RNA_def_int(ot->srna, "type", 0, 0, 10, "Bone Group Index", "", 0, INT_MAX);
1269 }
1270
1271
1272 static int pose_group_unassign_exec (bContext *C, wmOperator *op)
1273 {
1274         ScrArea *sa= CTX_wm_area(C);
1275         Object *ob;
1276         bArmature *arm;
1277         bPose *pose;
1278         short done= 0;
1279         
1280         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1281         if (sa->spacetype == SPACE_BUTS) 
1282                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1283         else
1284                 ob= CTX_data_active_object(C);
1285         
1286         /* only continue if there's an object, and a pose there too */
1287         if (ELEM(NULL, ob, ob->pose))
1288                 return OPERATOR_CANCELLED;
1289         pose= ob->pose;
1290         arm= ob->data;
1291         
1292         /* find selected bones to remove from all bone groups */
1293         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1294         {
1295                 if (pchan->agrp_index) {
1296                         pchan->agrp_index= 0;
1297                         done= 1;
1298                 }
1299         }
1300         CTX_DATA_END;
1301         
1302         /* notifiers for updates */
1303         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1304         
1305         /* report done status */
1306         if (done)
1307                 return OPERATOR_FINISHED;
1308         else
1309                 return OPERATOR_CANCELLED;
1310 }
1311
1312 void POSE_OT_group_unassign (wmOperatorType *ot)
1313 {
1314         /* identifiers */
1315         ot->name= "Remove Selected from Bone Groups";
1316         ot->idname= "POSE_OT_group_unassign";
1317         ot->description= "Remove selected bones from all bone groups";
1318         
1319         /* api callbacks */
1320         ot->exec= pose_group_unassign_exec;
1321         ot->poll= ED_operator_posemode;
1322         
1323         /* flags */
1324         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1325 }
1326
1327 static void pose_group_select(bContext *C, Object *ob, int select)
1328 {
1329         bPose *pose= ob->pose;
1330         
1331         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, visible_pose_bones)
1332         {
1333                 if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) {
1334                         if (select) {
1335                                 if (pchan->agrp_index == pose->active_group) 
1336                                         pchan->bone->flag |= BONE_SELECTED;
1337                         }
1338                         else {
1339                                 if (pchan->agrp_index == pose->active_group) 
1340                                         pchan->bone->flag &= ~BONE_SELECTED;
1341                         }
1342                 }
1343         }
1344         CTX_DATA_END;
1345 }
1346
1347 static int pose_group_select_exec (bContext *C, wmOperator *op)
1348 {
1349         ScrArea *sa= CTX_wm_area(C);
1350         Object *ob;
1351         
1352         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1353         if (sa->spacetype == SPACE_BUTS) 
1354                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1355         else
1356                 ob= CTX_data_active_object(C);
1357         
1358         /* only continue if there's an object, and a pose there too */
1359         if (ELEM(NULL, ob, ob->pose))
1360                 return OPERATOR_CANCELLED;
1361         
1362         pose_group_select(C, ob, 1);
1363         
1364         /* notifiers for updates */
1365         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1366         
1367         return OPERATOR_FINISHED;
1368 }
1369
1370 void POSE_OT_group_select (wmOperatorType *ot)
1371 {
1372         /* identifiers */
1373         ot->name= "Select Bones of Bone Group";
1374         ot->idname= "POSE_OT_group_select";
1375         ot->description= "Select bones in active Bone Group";
1376         
1377         /* api callbacks */
1378         ot->exec= pose_group_select_exec;
1379         ot->poll= ED_operator_posemode;
1380         
1381         /* flags */
1382         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1383 }
1384
1385 static int pose_group_deselect_exec (bContext *C, wmOperator *op)
1386 {
1387         ScrArea *sa= CTX_wm_area(C);
1388         Object *ob;
1389         
1390         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1391         if (sa->spacetype == SPACE_BUTS) 
1392                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1393         else
1394                 ob= CTX_data_active_object(C);
1395         
1396         /* only continue if there's an object, and a pose there too */
1397         if (ELEM(NULL, ob, ob->pose))
1398                 return OPERATOR_CANCELLED;
1399         
1400         pose_group_select(C, ob, 0);
1401         
1402         /* notifiers for updates */
1403         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1404         
1405         return OPERATOR_FINISHED;
1406 }
1407
1408 void POSE_OT_group_deselect (wmOperatorType *ot)
1409 {
1410         /* identifiers */
1411         ot->name= "Deselecte Bone Group";
1412         ot->idname= "POSE_OT_group_deselect";
1413         ot->description= "Deselect bones of active Bone Group";
1414         
1415         /* api callbacks */
1416         ot->exec= pose_group_deselect_exec;
1417         ot->poll= ED_operator_posemode;
1418         
1419         /* flags */
1420         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1421 }
1422
1423 /* ********************************************** */
1424
1425 static int pose_flip_names_exec (bContext *C, wmOperator *op)
1426 {
1427         Object *ob= CTX_data_active_object(C);
1428         bArmature *arm;
1429         
1430         /* paranoia checks */
1431         if (ELEM(NULL, ob, ob->pose)) 
1432                 return OPERATOR_CANCELLED;
1433         arm= ob->data;
1434         
1435         /* loop through selected bones, auto-naming them */
1436         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1437         {
1438                 char newname[32];
1439                 flip_side_name(newname, pchan->name, TRUE);
1440                 ED_armature_bone_rename(arm, pchan->name, newname);
1441         }
1442         CTX_DATA_END;
1443         
1444         /* since we renamed stuff... */
1445         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1446
1447         /* note, notifier might evolve */
1448         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1449         
1450         return OPERATOR_FINISHED;
1451 }
1452
1453 void POSE_OT_flip_names (wmOperatorType *ot)
1454 {
1455         /* identifiers */
1456         ot->name= "Flip Names";
1457         ot->idname= "POSE_OT_flip_names";
1458         ot->description= "Flips (and corrects) the names of selected bones";
1459         
1460         /* api callbacks */
1461         ot->exec= pose_flip_names_exec;
1462         ot->poll= ED_operator_posemode;
1463         
1464         /* flags */
1465         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1466 }
1467
1468 /* ------------------ */
1469
1470 static int pose_autoside_names_exec (bContext *C, wmOperator *op)
1471 {
1472         Object *ob= CTX_data_active_object(C);
1473         bArmature *arm;
1474         char newname[32];
1475         short axis= RNA_enum_get(op->ptr, "axis");
1476         
1477         /* paranoia checks */
1478         if (ELEM(NULL, ob, ob->pose)) 
1479                 return OPERATOR_CANCELLED;
1480         arm= ob->data;
1481         
1482         /* loop through selected bones, auto-naming them */
1483         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1484         {
1485                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1486                 if(bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]))
1487                         ED_armature_bone_rename(arm, pchan->name, newname);
1488         }
1489         CTX_DATA_END;
1490         
1491         /* since we renamed stuff... */
1492         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1493
1494         /* note, notifier might evolve */
1495         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1496         
1497         return OPERATOR_FINISHED;
1498 }
1499
1500 void POSE_OT_autoside_names (wmOperatorType *ot)
1501 {
1502         static EnumPropertyItem axis_items[]= {
1503                  {0, "XAXIS", 0, "X-Axis", "Left/Right"},
1504                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
1505                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
1506                 {0, NULL, 0, NULL, NULL}};
1507         
1508         /* identifiers */
1509         ot->name= "AutoName by Axis";
1510         ot->idname= "POSE_OT_autoside_names";
1511         ot->description= "Automatically renames the selected bones according to which side of the target axis they fall on";
1512         
1513         /* api callbacks */
1514         ot->invoke= WM_menu_invoke;
1515         ot->exec= pose_autoside_names_exec;
1516         ot->poll= ED_operator_posemode;
1517         
1518         /* flags */
1519         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1520         
1521         /* settings */
1522         ot->prop= RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with.");
1523 }
1524
1525 /* ********************************************** */
1526
1527 /* context active object, or weightpainted object with armature in posemode */
1528 void pose_activate_flipped_bone(Scene *scene)
1529 {
1530         Object *ob= OBACT;
1531         bArmature *arm= ob->data;
1532         
1533         if(ob==NULL) return;
1534
1535         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
1536                 ob= modifiers_isDeformedByArmature(ob);
1537         }
1538         if(ob && (ob->mode & OB_MODE_POSE)) {
1539                 bPoseChannel *pchanf;
1540                 
1541                 if(arm->act_bone) {
1542                         char name[32];
1543                         flip_side_name(name, arm->act_bone->name, TRUE);
1544
1545                         pchanf= get_pose_channel(ob->pose, name);
1546                         if(pchanf && pchanf->bone != arm->act_bone) {
1547                                 arm->act_bone->flag &= ~BONE_SELECTED;
1548                                 pchanf->bone->flag |= BONE_SELECTED;
1549
1550                                 arm->act_bone= pchanf->bone;
1551
1552                                 /* in weightpaint we select the associated vertex group too */
1553                                 if(ob->mode & OB_MODE_WEIGHT_PAINT) {
1554                                         ED_vgroup_select_by_name(OBACT, name);
1555                                         DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA);
1556                                 }
1557                                 
1558                                 // XXX notifiers need to be sent to other editors to update
1559                                 
1560                         }                       
1561                 }
1562         }
1563 }
1564
1565
1566 /* ********************************************** */
1567
1568 /* Present a popup to get the layers that should be used */
1569 static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1570 {
1571         Object *ob= CTX_data_active_object(C);
1572         bArmature *arm= (ob)? ob->data : NULL;
1573         PointerRNA ptr;
1574         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1575         
1576         /* sanity checking */
1577         if (arm == NULL)
1578                 return OPERATOR_CANCELLED;
1579                 
1580         /* get RNA pointer to armature data to use that to retrieve the layers as ints to init the operator */
1581         RNA_id_pointer_create((ID *)arm, &ptr);
1582         RNA_boolean_get_array(&ptr, "layer", layers);
1583         RNA_boolean_set_array(op->ptr, "layers", layers);
1584         
1585         /* part to sync with other similar operators... */
1586         return WM_operator_props_popup(C, op, evt);
1587 }
1588
1589 /* Set the visible layers for the active armature (edit and pose modes) */
1590 static int pose_armature_layers_exec (bContext *C, wmOperator *op)
1591 {
1592         Object *ob= CTX_data_active_object(C);
1593         bArmature *arm= (ob)? ob->data : NULL;
1594         PointerRNA ptr;
1595         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1596         
1597         /* get the values set in the operator properties */
1598         RNA_boolean_get_array(op->ptr, "layers", layers);
1599         
1600         /* get pointer for armature, and write data there... */
1601         RNA_id_pointer_create((ID *)arm, &ptr);
1602         RNA_boolean_set_array(&ptr, "layer", layers);
1603         
1604         /* note, notifier might evolve */
1605         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1606         
1607         return OPERATOR_FINISHED;
1608 }
1609
1610
1611 void POSE_OT_armature_layers (wmOperatorType *ot)
1612 {
1613         /* identifiers */
1614         ot->name= "Change Armature Layers";
1615         ot->idname= "POSE_OT_armature_layers";
1616         ot->description= "Change the visible armature layers";
1617         
1618         /* callbacks */
1619         ot->invoke= pose_armature_layers_invoke;
1620         ot->exec= pose_armature_layers_exec;
1621         ot->poll= ED_operator_posemode;
1622         
1623         /* flags */
1624         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1625         
1626         /* properties */
1627         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
1628 }
1629
1630 void ARMATURE_OT_armature_layers (wmOperatorType *ot)
1631 {
1632         /* identifiers */
1633         ot->name= "Change Armature Layers";
1634         ot->idname= "ARMATURE_OT_armature_layers";
1635         ot->description= "Change the visible armature layers";
1636         
1637         /* callbacks */
1638         ot->invoke= pose_armature_layers_invoke;
1639         ot->exec= pose_armature_layers_exec;
1640         ot->poll= ED_operator_editarmature;
1641         
1642         /* flags */
1643         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1644         
1645         /* properties */
1646         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
1647 }
1648
1649 /* ------------------- */
1650
1651 /* Present a popup to get the layers that should be used */
1652 static int pose_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1653 {
1654         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1655         
1656         /* get layers that are active already */
1657         memset(&layers, 0, sizeof(layers)); /* set all layers to be off by default */
1658         
1659         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) 
1660         {
1661                 short bit;
1662                 
1663                 /* loop over the bits for this pchan's layers, adding layers where they're needed */
1664                 for (bit= 0; bit < 32; bit++) {
1665                         if (pchan->bone->layer & (1<<bit))
1666                                 layers[bit]= 1;
1667                 }
1668         }
1669         CTX_DATA_END;
1670         
1671         /* copy layers to operator */
1672         RNA_boolean_set_array(op->ptr, "layers", layers);
1673         
1674                 /* part to sync with other similar operators... */
1675         return WM_operator_props_popup(C, op, evt);
1676 }
1677
1678 /* Set the visible layers for the active armature (edit and pose modes) */
1679 static int pose_bone_layers_exec (bContext *C, wmOperator *op)
1680 {
1681         Object *ob= CTX_data_active_object(C);
1682         bArmature *arm= (ob)? ob->data : NULL;
1683         PointerRNA ptr;
1684         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1685         
1686         /* get the values set in the operator properties */
1687         RNA_boolean_get_array(op->ptr, "layers", layers);
1688         
1689         /* set layers of pchans based on the values set in the operator props */
1690         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) 
1691         {
1692                 /* get pointer for pchan, and write flags this way */
1693                 RNA_pointer_create((ID *)arm, &RNA_Bone, pchan->bone, &ptr);
1694                 RNA_boolean_set_array(&ptr, "layer", layers);
1695         }
1696         CTX_DATA_END;
1697         
1698         /* note, notifier might evolve */
1699         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1700         
1701         return OPERATOR_FINISHED;
1702 }
1703
1704 void POSE_OT_bone_layers (wmOperatorType *ot)
1705 {
1706         /* identifiers */
1707         ot->name= "Change Bone Layers";
1708         ot->idname= "POSE_OT_bone_layers";
1709         ot->description= "Change the layers that the selected bones belong to";
1710         
1711         /* callbacks */
1712         ot->invoke= pose_bone_layers_invoke;
1713         ot->exec= pose_bone_layers_exec;
1714         ot->poll= ED_operator_posemode;
1715         
1716         /* flags */
1717         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1718         
1719         /* properties */
1720         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
1721 }
1722
1723 /* ------------------- */
1724
1725 /* Present a popup to get the layers that should be used */
1726 static int armature_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1727 {
1728         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1729         
1730         /* get layers that are active already */
1731         memset(&layers, 0, sizeof(layers)); /* set all layers to be off by default */
1732         
1733         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) 
1734         {
1735                 short bit;
1736                 
1737                 /* loop over the bits for this pchan's layers, adding layers where they're needed */
1738                 for (bit= 0; bit < 32; bit++) {
1739                         if (ebone->layer & (1<<bit))
1740                                 layers[bit]= 1;
1741                 }
1742         }
1743         CTX_DATA_END;
1744         
1745         /* copy layers to operator */
1746         RNA_boolean_set_array(op->ptr, "layers", layers);
1747         
1748                 /* part to sync with other similar operators... */
1749         return WM_operator_props_popup(C, op, evt);
1750 }
1751
1752 /* Set the visible layers for the active armature (edit and pose modes) */
1753 static int armature_bone_layers_exec (bContext *C, wmOperator *op)
1754 {
1755         Object *ob= CTX_data_edit_object(C);
1756         bArmature *arm= (ob)? ob->data : NULL;
1757         PointerRNA ptr;
1758         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1759         
1760         /* get the values set in the operator properties */
1761         RNA_boolean_get_array(op->ptr, "layers", layers);
1762         
1763         /* set layers of pchans based on the values set in the operator props */
1764         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) 
1765         {
1766                 /* get pointer for pchan, and write flags this way */
1767                 RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr);
1768                 RNA_boolean_set_array(&ptr, "layer", layers);
1769         }
1770         CTX_DATA_END;
1771         
1772         /* note, notifier might evolve */
1773         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1774         
1775         return OPERATOR_FINISHED;
1776 }
1777
1778 void ARMATURE_OT_bone_layers (wmOperatorType *ot)
1779 {
1780         /* identifiers */
1781         ot->name= "Change Bone Layers";
1782         ot->idname= "ARMATURE_OT_bone_layers";
1783         ot->description= "Change the layers that the selected bones belong to";
1784         
1785         /* callbacks */
1786         ot->invoke= armature_bone_layers_invoke;
1787         ot->exec= armature_bone_layers_exec;
1788         ot->poll= ED_operator_editarmature;
1789         
1790         /* flags */
1791         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1792         
1793         /* properties */
1794         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
1795 }
1796
1797 /* ********************************************** */
1798
1799 static int pose_flip_quats_exec (bContext *C, wmOperator *op)
1800 {
1801         Scene *scene= CTX_data_scene(C);
1802         Object *ob= CTX_data_active_object(C);
1803         KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
1804         
1805         /* loop through all selected pchans, flipping and keying (as needed) */
1806         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1807         {
1808                 /* only if bone is using quaternion rotation */
1809                 if (pchan->rotmode == ROT_MODE_QUAT) {
1810                         /* quaternions have 720 degree range */
1811                         pchan->quat[0]= -pchan->quat[0];
1812                         pchan->quat[1]= -pchan->quat[1];
1813                         pchan->quat[2]= -pchan->quat[2];
1814                         pchan->quat[3]= -pchan->quat[3];
1815                         
1816                         /* tagging */
1817                         if (autokeyframe_cfra_can_key(scene, &ob->id)) {
1818                                 ListBase dsources = {NULL, NULL};
1819                                 
1820                                 /* now insert the keyframe(s) using the Keying Set
1821                                  *      1) add datasource override for the PoseChannel
1822                                  *      2) insert keyframes
1823                                  *      3) free the extra info 
1824                                  */
1825                                 ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan); 
1826                                 ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
1827                                 BLI_freelistN(&dsources);
1828                                 
1829                                 /* clear any unkeyed tags */
1830                                 if (pchan->bone)
1831                                         pchan->bone->flag &= ~BONE_UNKEYED;
1832                         }
1833                         else {
1834                                 /* add unkeyed tags */
1835                                 if (pchan->bone)
1836                                         pchan->bone->flag |= BONE_UNKEYED;
1837                         }
1838                 }
1839         }
1840         CTX_DATA_END;
1841         
1842         /* notifiers and updates */
1843         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1844         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
1845         
1846         return OPERATOR_FINISHED;
1847 }
1848
1849 void POSE_OT_quaternions_flip (wmOperatorType *ot)
1850 {
1851         /* identifiers */
1852         ot->name = "Flip Quats";
1853         ot->idname= "POSE_OT_quaternions_flip";
1854         ot->description= "Flip quaternion values to achieve desired rotations, while maintaining the same orientations";
1855         
1856         /* callbacks */
1857         ot->exec= pose_flip_quats_exec;
1858         ot->poll= ED_operator_posemode;
1859         
1860         /* flags */
1861         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1862 }
1863
1864 /* ********************************************** */
1865
1866 /* context: active channel */
1867 void pose_special_editmenu(Scene *scene)
1868 {
1869 #if 0
1870         Object *obedit= scene->obedit; // XXX context
1871         Object *ob= OBACT;
1872         short nr;
1873         
1874         /* paranoia checks */
1875         if(!ob && !ob->pose) return;
1876         if(ob==obedit || (ob->mode & OB_MODE_POSE)==0) return;
1877         
1878         nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6|%l|AutoName Left-Right%x7|AutoName Front-Back%x8|AutoName Top-Bottom%x9");
1879         if(nr==1) {
1880                 pose_select_constraint_target(scene);
1881         }
1882         else if(nr==2) {
1883                 pose_flip_names();
1884         }
1885         else if(nr==3) {
1886                 pose_calculate_path(C, ob);
1887         }
1888         else if(nr==4) {
1889                 pose_clear_paths(ob);
1890         }
1891         else if(nr==5) {
1892                 pose_clear_user_transforms(scene, ob);
1893         }
1894         else if(nr==6) {
1895                 pose_relax();
1896         }
1897         else if(ELEM3(nr, 7, 8, 9)) {
1898                 pose_autoside_names(nr-7);
1899         }
1900 #endif
1901 }
1902
1903 /* Restore selected pose-bones to 'action'-defined pose */
1904 void pose_clear_user_transforms(Scene *scene, Object *ob)
1905 {
1906         bArmature *arm= ob->data;
1907         bPoseChannel *pchan;
1908         
1909         if (ob->pose == NULL)
1910                 return;
1911         
1912         /* if the object has an action, restore pose to the pose defined by the action by clearing pose on selected bones */
1913         if (ob->action) {
1914                 /* find selected bones */
1915                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1916                         if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1917                                 /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */
1918                                 pchan->bone->flag &= ~BONE_UNKEYED;
1919                         }
1920                 }
1921                 
1922                 /* clear pose locking flag 
1923                  *      - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared
1924                  */
1925                 ob->pose->flag |= POSE_DO_UNLOCK;
1926         }
1927         else {
1928                 /* no action, so restore entire pose to rest pose (cannot restore only selected bones) */
1929                 rest_pose(ob->pose);
1930         }
1931         
1932         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1933         BIF_undo_push("Clear User Transform");
1934 }
1935