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