batch remove .'s used with RNA_def_struct_ui_text
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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_action_types.h"
42 #include "DNA_armature_types.h"
43 #include "DNA_constraint_types.h"
44 #include "DNA_curve_types.h"
45 #include "DNA_mesh_types.h"
46 #include "DNA_meshdata_types.h"
47 #include "DNA_modifier_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_scene_types.h"
50 #include "DNA_screen_types.h"
51 #include "DNA_view3d_types.h"
52 #include "DNA_userdef_types.h"
53
54 #include "BKE_anim.h"
55 #include "BKE_animsys.h"
56 #include "BKE_action.h"
57 #include "BKE_armature.h"
58 #include "BKE_blender.h"
59 #include "BKE_context.h"
60 #include "BKE_constraint.h"
61 #include "BKE_deform.h"
62 #include "BKE_depsgraph.h"
63 #include "BKE_displist.h"
64 #include "BKE_fcurve.h"
65 #include "BKE_global.h"
66 #include "BKE_modifier.h"
67 #include "BKE_object.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_report.h"
70
71 #include "BIF_gl.h"
72
73 #include "RNA_access.h"
74 #include "RNA_define.h"
75
76 #include "WM_api.h"
77 #include "WM_types.h"
78
79 #include "ED_armature.h"
80 #include "ED_anim_api.h"
81 #include "ED_keyframing.h"
82 #include "ED_object.h"
83 #include "ED_mesh.h"
84 #include "ED_screen.h"
85 #include "ED_transform.h" /* for autokey TFM_TRANSLATION, etc */
86 #include "ED_view3d.h"
87
88 #include "UI_interface.h"
89
90 #include "armature_intern.h"
91
92 /* ************* XXX *************** */
93 static int pupmenu() {return 0;}
94 static void error() {};
95 static void BIF_undo_push() {}
96 /* ************* XXX *************** */
97
98 /* This function is used to indicate that a bone is selected and needs keyframes inserted */
99 void set_pose_keys (Object *ob)
100 {
101         bArmature *arm= ob->data;
102         bPoseChannel *chan;
103
104         if (ob->pose){
105                 for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
106                         Bone *bone= chan->bone;
107                         if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
108                                 chan->flag |= POSE_KEY; 
109                         else
110                                 chan->flag &= ~POSE_KEY;
111                 }
112         }
113 }
114
115 /* This function is used to process the necessary updates for */
116 void ED_armature_enter_posemode(bContext *C, Base *base)
117 {
118         Object *ob= base->object;
119         
120         if (ob->id.lib){
121                 error ("Can't pose libdata");
122                 return;
123         }
124         
125         switch (ob->type){
126                 case OB_ARMATURE:
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_POSE, NULL);
131                         
132                         break;
133                 default:
134                         return;
135         }
136
137         //ED_object_toggle_modes(C, ob->mode);
138 }
139
140 void ED_armature_exit_posemode(bContext *C, Base *base)
141 {
142         if(base) {
143                 Object *ob= base->object;
144                 
145                 ob->restore_mode = ob->mode;
146                 ob->mode &= ~OB_MODE_POSE;
147                 
148                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
149         }       
150 }
151
152 /* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */
153 /* only_selected==1 : the active bone is allowed to be protected */
154 static short pose_has_protected_selected(Object *ob, short only_selected, short warn)
155 {
156         /* check protection */
157         if (ob->proxy) {
158                 bPoseChannel *pchan;
159                 bArmature *arm= ob->data;
160
161                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
162                         if (pchan->bone && (pchan->bone->layer & arm->layer)) {
163                                 if (pchan->bone->layer & arm->layer_protected) {
164                                         if (only_selected && (pchan->bone == arm->act_bone));
165                                         else if (pchan->bone->flag & BONE_SELECTED || pchan->bone == arm->act_bone)
166                                            break;
167                                 }
168                         }
169                 }
170                 if (pchan) {
171                         if (warn) error("Cannot change Proxy protected bones");
172                         return 1;
173                 }
174         }
175         return 0;
176 }
177
178 /* only for real IK, not for auto-IK */
179 int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
180 {
181         bConstraint *con;
182         Bone *bone;
183         
184         /* No need to check if constraint is active (has influence),
185          * since all constraints with CONSTRAINT_IK_AUTO are active */
186         for(con= pchan->constraints.first; con; con= con->next) {
187                 if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
188                         bKinematicConstraint *data= con->data;
189                         if((data->flag & CONSTRAINT_IK_AUTO)==0)
190                                 return 1;
191                 }
192         }
193         for(bone= pchan->bone->childbase.first; bone; bone= bone->next) {
194                 pchan= get_pose_channel(ob->pose, bone->name);
195                 if(pchan && ED_pose_channel_in_IK_chain(ob, pchan))
196                         return 1;
197         }
198         return 0;
199 }
200
201 /* ********************************************** */
202 /* Motion Paths */
203
204 /* For the object with pose/action: update paths for those that have got them
205  * This should selectively update paths that exist...
206  *
207  * To be called from various tools that do incremental updates 
208  */
209 void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
210 {
211         ListBase targets = {NULL, NULL};
212         
213         /* set flag to force recalc, then grab the relevant bones to target */
214         ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
215         animviz_get_object_motionpaths(ob, &targets);
216         
217         /* recalculate paths, then free */
218         animviz_calc_motionpaths(scene, &targets);
219         BLI_freelistN(&targets);
220 }
221
222 /* For the object with pose/action: create path curves for selected bones 
223  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
224  */
225 static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
226 {
227         ScrArea *sa= CTX_wm_area(C);
228         Scene *scene= CTX_data_scene(C);
229         Object *ob;
230         
231         /* since this call may also be used from the buttons window, we need to check for where to get the object */
232         if (sa->spacetype == SPACE_BUTS) 
233                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
234         else
235                 ob= CTX_data_active_object(C);
236                 
237         if (ELEM(NULL, ob, ob->pose))
238                 return OPERATOR_CANCELLED;
239         
240         /* set up path data for bones being calculated */
241         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
242         {
243                 /* verify makes sure that the selected bone has a bone with the appropriate settings */
244                 animviz_verify_motionpaths(scene, ob, pchan);
245         }
246         CTX_DATA_END;
247         
248         /* calculate the bones that now have motionpaths... */
249         // TODO: only make for the selected bones?
250         ED_pose_recalculate_paths(C, scene, ob);
251         
252         /* notifiers for updates */
253         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
254         
255         return OPERATOR_FINISHED; 
256 }
257
258 void POSE_OT_paths_calculate (wmOperatorType *ot)
259 {
260         /* identifiers */
261         ot->name= "Calculate Bone Paths";
262         ot->idname= "POSE_OT_paths_calculate";
263         ot->description= "Calculate paths for the selected bones";
264         
265         /* api callbacks */
266         ot->exec= pose_calculate_paths_exec;
267         ot->poll= ED_operator_posemode;
268         
269         /* flags */
270         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
271 }
272
273 /* --------- */
274
275 /* for the object with pose/action: clear path curves for selected bones only */
276 void ED_pose_clear_paths(Object *ob)
277 {
278         bPoseChannel *pchan;
279         
280         if ELEM(NULL, ob, ob->pose)
281                 return;
282         
283         /* free the motionpath blocks */
284         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
285                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
286                         if (pchan->mpath) {
287                                 animviz_free_motionpath(pchan->mpath);
288                                 pchan->mpath= NULL;
289                         }
290                 }
291         }
292 }
293
294 /* operator callback for this */
295 static int pose_clear_paths_exec (bContext *C, wmOperator *op)
296 {
297         ScrArea *sa= CTX_wm_area(C);
298         Object *ob;
299         
300         /* since this call may also be used from the buttons window, we need to check for where to get the object */
301         if (sa->spacetype == SPACE_BUTS) 
302                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
303         else
304                 ob= CTX_data_active_object(C);
305                 
306         /* only continue if there's an object */
307         if ELEM(NULL, ob, ob->pose)
308                 return OPERATOR_CANCELLED;
309         
310         /* use the backend function for this */
311         ED_pose_clear_paths(ob);
312         
313         /* notifiers for updates */
314         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
315         
316         return OPERATOR_FINISHED; 
317 }
318
319 void POSE_OT_paths_clear (wmOperatorType *ot)
320 {
321         /* identifiers */
322         ot->name= "Clear Bone Paths";
323         ot->idname= "POSE_OT_paths_clear";
324         ot->description= "Clear path caches for selected bones";
325         
326         /* api callbacks */
327         ot->exec= pose_clear_paths_exec;
328         ot->poll= ED_operator_posemode;
329         
330         /* flags */
331         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
332 }
333
334 /* ******************* Select Constraint Target Operator ************* */
335
336 static int pose_select_constraint_target_exec(bContext *C, wmOperator *op)
337 {
338         Object *ob= CTX_data_active_object(C);
339         bArmature *arm= ob->data;
340         bConstraint *con;
341         int found= 0;
342         
343         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
344         {
345                 if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) {
346                         for (con= pchan->constraints.first; con; con= con->next) {
347                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
348                                 ListBase targets = {NULL, NULL};
349                                 bConstraintTarget *ct;
350                                 
351                                 if (cti && cti->get_constraint_targets) {
352                                         cti->get_constraint_targets(con, &targets);
353                                         
354                                         for (ct= targets.first; ct; ct= ct->next) {
355                                                 if ((ct->tar == ob) && (ct->subtarget[0])) {
356                                                         bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
357                                                         if((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) {
358                                                                 pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
359                                                                 found= 1;
360                                                         }
361                                                 }
362                                         }
363                                         
364                                         if (cti->flush_constraint_targets)
365                                                 cti->flush_constraint_targets(con, &targets, 1);
366                                 }
367                         }
368                 }
369         }
370         CTX_DATA_END;
371
372         if (!found)
373                 return OPERATOR_CANCELLED;
374
375         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
376
377         return OPERATOR_FINISHED;
378 }
379
380 void POSE_OT_select_constraint_target(wmOperatorType *ot)
381 {
382         /* identifiers */
383         ot->name= "Select Constraint Target";
384         ot->idname= "POSE_OT_select_constraint_target";
385         
386         /* api callbacks */
387         ot->exec= pose_select_constraint_target_exec;
388         ot->poll= ED_operator_posemode;
389         
390         /* flags */
391         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
392 }
393
394 /* ******************* select hierarchy operator ************* */
395
396 static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
397 {
398         Object *ob= CTX_data_active_object(C);
399         bArmature *arm= ob->data;
400         Bone *curbone, *pabone, *chbone;
401         int direction = RNA_enum_get(op->ptr, "direction");
402         int add_to_sel = RNA_boolean_get(op->ptr, "extend");
403         int found= 0;
404         
405         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
406         {
407                 curbone= pchan->bone;
408                 
409                 if ((curbone->flag & BONE_UNSELECTABLE)==0) {
410                         if (curbone == arm->act_bone) {
411                                 if (direction == BONE_SELECT_PARENT) {
412                                         if (pchan->parent == NULL) continue;
413                                         else pabone= pchan->parent->bone;
414                                         
415                                         if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_P)) {
416                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
417                                                 pabone->flag |= BONE_SELECTED;
418                                                 arm->act_bone= pabone;
419                                                 
420                                                 found= 1;
421                                                 break;
422                                         }
423                                 } 
424                                 else { /* direction == BONE_SELECT_CHILD */
425                                         if (pchan->child == NULL) continue;
426                                         else chbone = pchan->child->bone;
427                                         
428                                         if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_P)) {
429                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
430                                                 chbone->flag |= BONE_SELECTED;
431                                                 arm->act_bone= chbone;
432                                                 
433                                                 found= 1;
434                                                 break;
435                                         }
436                                 }
437                         }
438                 }
439         }
440         CTX_DATA_END;
441
442         if (found == 0)
443                 return OPERATOR_CANCELLED;
444
445         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
446
447         return OPERATOR_FINISHED;
448 }
449
450 void POSE_OT_select_hierarchy(wmOperatorType *ot)
451 {
452         static EnumPropertyItem direction_items[]= {
453         {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
454         {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
455         {0, NULL, 0, NULL, NULL}
456         };
457         
458         /* identifiers */
459         ot->name= "Select Hierarchy";
460         ot->idname= "POSE_OT_select_hierarchy";
461         
462         /* api callbacks */
463         ot->exec= pose_select_hierarchy_exec;
464         ot->poll= ED_operator_posemode;
465         
466         /* flags */
467         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
468         
469         /* props */
470         ot->prop= RNA_def_enum(ot->srna, "direction", direction_items, BONE_SELECT_PARENT, "Direction", "");
471         RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
472         
473 }
474
475 /* ******************* select grouped operator ************* */
476
477 static short pose_select_same_group (bContext *C, Object *ob, short extend)
478 {
479         bArmature *arm= (ob)? ob->data : NULL;
480         bPose *pose= (ob)? ob->pose : NULL;
481         char *group_flags;
482         int numGroups = 0;
483         short changed=0, tagged=0;
484         
485         /* sanity checks */
486         if (ELEM3(NULL, ob, pose, arm))
487                 return 0;
488                 
489         /* count the number of groups */
490         numGroups= BLI_countlist(&pose->agroups);
491         if (numGroups == 0)
492                 return 0;
493                 
494         /* alloc a small array to keep track of the groups to use 
495          *      - each cell stores on/off state for whether group should be used
496          *      - size is numGroups + 1, since index=0 is used for no-group
497          */
498         group_flags= MEM_callocN(numGroups+1, "pose_select_same_group");
499         
500         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
501         {
502                 /* keep track of group as group to use later? */
503                 if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) {
504                         group_flags[pchan->agrp_index] = 1;
505                         tagged= 1;
506                 }
507                 
508                 /* deselect all bones before selecting new ones? */
509                 if ((extend == 0) && (pchan->bone->flag & BONE_UNSELECTABLE)==0)
510                         pchan->bone->flag &= ~BONE_SELECTED;
511         }
512         CTX_DATA_END;
513         
514         /* small optimisation: only loop through bones a second time if there are any groups tagged */
515         if (tagged) {
516                 /* only if group matches (and is not selected or current bone) */
517                 CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
518                 {
519                         if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) {
520                                 /* check if the group used by this bone is counted */
521                                 if (group_flags[pchan->agrp_index]) {
522                                         pchan->bone->flag |= BONE_SELECTED;
523                                         changed= 1;
524                                 }
525                         }
526                 }
527                 CTX_DATA_END;
528         }
529         
530         /* free temp info */
531         MEM_freeN(group_flags);
532         
533         return changed;
534 }
535
536 static short pose_select_same_layer (bContext *C, Object *ob, short extend)
537 {
538         bPose *pose= (ob)? ob->pose : NULL;
539         bArmature *arm= (ob)? ob->data : NULL;
540         short changed= 0;
541         int layers= 0;
542         
543         if (ELEM3(NULL, ob, pose, arm))
544                 return 0;
545         
546         /* figure out what bones are selected */
547         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
548         {
549                 /* keep track of layers to use later? */
550                 if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone))
551                         layers |= pchan->bone->layer;
552                         
553                 /* deselect all bones before selecting new ones? */
554                 if ((extend == 0) && (pchan->bone->flag & BONE_UNSELECTABLE)==0)
555                         pchan->bone->flag &= ~BONE_SELECTED;
556         }
557         CTX_DATA_END;
558         if (layers == 0) 
559                 return 0;
560                 
561         /* select bones that are on same layers as layers flag */
562         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
563         {
564                 /* if bone is on a suitable layer, and the bone can have its selection changed, select it */
565                 if ((layers & pchan->bone->layer) && (pchan->bone->flag & BONE_UNSELECTABLE)==0) {
566                         pchan->bone->flag |= BONE_SELECTED;
567                         changed= 1;
568                 }
569         }
570         CTX_DATA_END;
571         
572         return changed;
573 }
574
575
576 static int pose_select_grouped_exec (bContext *C, wmOperator *op)
577 {
578         Object *ob= CTX_data_active_object(C);
579         short extend= RNA_boolean_get(op->ptr, "extend");
580         short changed = 0;
581         
582         /* sanity check */
583         if (ELEM(NULL, ob, ob->pose))
584                 return OPERATOR_CANCELLED;
585                 
586         /* selection types 
587          * NOTE: for the order of these, see the enum in POSE_OT_select_grouped()
588          */
589         switch (RNA_enum_get(op->ptr, "type")) {
590                 case 1: /* group */
591                         changed= pose_select_same_group(C, ob, extend);
592                         break;
593                 default: /* layer */
594                         changed= pose_select_same_layer(C, ob, extend);
595                         break;
596         }
597         
598         /* notifiers for updates */
599         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
600         
601         /* report done status */
602         if (changed)
603                 return OPERATOR_FINISHED;
604         else
605                 return OPERATOR_CANCELLED;
606 }
607
608 void POSE_OT_select_grouped (wmOperatorType *ot)
609 {
610         static EnumPropertyItem prop_select_grouped_types[] = {
611                 {0, "LAYER", 0, "Layer", "Shared layers"},
612                 {1, "GROUP", 0, "Group", "Shared group"},
613                 {0, NULL, 0, NULL, NULL}
614         };
615
616         /* identifiers */
617         ot->name= "Select Grouped";
618         ot->description = "Select all visible bones grouped by various properties";
619         ot->idname= "POSE_OT_select_grouped";
620         
621         /* api callbacks */
622         ot->invoke= WM_menu_invoke;
623         ot->exec= pose_select_grouped_exec;
624         ot->poll= ED_operator_posemode;
625         
626         /* flags */
627         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
628         
629         /* properties */
630         RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
631         ot->prop= RNA_def_enum(ot->srna, "type", prop_select_grouped_types, 0, "Type", "");
632 }
633
634 /* ********************************************** */
635
636 void pose_copy_menu(Scene *scene)
637 {
638         Object *obedit= scene->obedit; // XXX context
639         Object *ob= OBACT;
640         bArmature *arm= ob->data;
641         bPoseChannel *pchan, *pchanact;
642         short nr=0;
643         int i=0;
644         
645         /* paranoia checks */
646         if (ELEM(NULL, ob, ob->pose)) return;
647         if ((ob==obedit) || (ob->mode & OB_MODE_POSE)==0) return;
648         
649         pchan= get_active_posechannel(ob);
650         
651         if (pchan==NULL) return;
652         pchanact= pchan;
653         
654         /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable, 
655          * but for constraints (just add local constraints)
656          */
657         if (pose_has_protected_selected(ob, 1, 0)) {
658                 i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
659                 if (i < 25)
660                         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");
661                 else
662                         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");
663         }
664         else {
665                 i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
666                 if (i < 25)
667                         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");
668                 else
669                         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");
670         }
671         
672         if (nr <= 0) 
673                 return;
674         
675         if (nr != 5)  {
676                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
677                         if ( (arm->layer & pchan->bone->layer) &&
678                                  (pchan->bone->flag & BONE_SELECTED) &&
679                                  (pchan != pchanact) ) 
680                         {
681                                 switch (nr) {
682                                         case 1: /* Local Location */
683                                                 VECCOPY(pchan->loc, pchanact->loc);
684                                                 break;
685                                         case 2: /* Local Rotation */
686                                                 QUATCOPY(pchan->quat, pchanact->quat);
687                                                 VECCOPY(pchan->eul, pchanact->eul);
688                                                 break;
689                                         case 3: /* Local Size */
690                                                 VECCOPY(pchan->size, pchanact->size);
691                                                 break;
692                                         case 4: /* All Constraints */
693                                         {
694                                                 ListBase tmp_constraints = {NULL, NULL};
695                                                 
696                                                 /* copy constraints to tmpbase and apply 'local' tags before 
697                                                  * appending to list of constraints for this channel
698                                                  */
699                                                 copy_constraints(&tmp_constraints, &pchanact->constraints);
700                                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
701                                                         bConstraint *con;
702                                                         
703                                                         /* add proxy-local tags */
704                                                         for (con= tmp_constraints.first; con; con= con->next)
705                                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
706                                                 }
707                                                 addlisttolist(&pchan->constraints, &tmp_constraints);
708                                                 
709                                                 /* update flags (need to add here, not just copy) */
710                                                 pchan->constflag |= pchanact->constflag;
711                                                 
712                                                 if (ob->pose)
713                                                         ob->pose->flag |= POSE_RECALC;
714                                         }
715                                                 break;
716                                         case 6: /* Transform Locks */
717                                                 pchan->protectflag = pchanact->protectflag;
718                                                 break;
719                                         case 7: /* IK (DOF) settings */
720                                         {
721                                                 pchan->ikflag = pchanact->ikflag;
722                                                 VECCOPY(pchan->limitmin, pchanact->limitmin);
723                                                 VECCOPY(pchan->limitmax, pchanact->limitmax);
724                                                 VECCOPY(pchan->stiffness, pchanact->stiffness);
725                                                 pchan->ikstretch= pchanact->ikstretch;
726                                                 pchan->ikrotweight= pchanact->ikrotweight;
727                                                 pchan->iklinweight= pchanact->iklinweight;
728                                         }
729                                                 break;
730                                         case 8: /* Custom Bone Shape */
731                                                 pchan->custom = pchanact->custom;
732                                                 break;
733                                         case 9: /* Visual Location */
734                                                 armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
735                                                 break;
736                                         case 10: /* Visual Rotation */
737                                         {
738                                                 float delta_mat[4][4];
739                                                 
740                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
741                                                 
742                                                 if (pchan->rotmode == ROT_MODE_AXISANGLE) {
743                                                         float tmp_quat[4];
744                                                         
745                                                         /* need to convert to quat first (in temp var)... */
746                                                         mat4_to_quat( tmp_quat,delta_mat);
747                                                         quat_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,tmp_quat);
748                                                 }
749                                                 else if (pchan->rotmode == ROT_MODE_QUAT)
750                                                         mat4_to_quat( pchan->quat,delta_mat);
751                                                 else
752                                                         mat4_to_eulO( pchan->eul, pchan->rotmode,delta_mat);
753                                         }
754                                                 break;
755                                         case 11: /* Visual Size */
756                                         {
757                                                 float delta_mat[4][4], size[4];
758                                                 
759                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
760                                                 mat4_to_size( size,delta_mat);
761                                                 VECCOPY(pchan->size, size);
762                                         }
763                                 }
764                         }
765                 }
766         } 
767         else { /* constraints, optional (note: max we can have is 24 constraints) */
768                 bConstraint *con, *con_back;
769                 int const_toggle[24];
770                 ListBase const_copy = {NULL, NULL};
771                 
772                 BLI_duplicatelist(&const_copy, &(pchanact->constraints));
773                 
774                 /* build the puplist of constraints */
775                 for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){
776                         const_toggle[i]= 1;
777 //                      add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
778                 }
779                 
780 //              if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
781 //                      BLI_freelistN(&const_copy);
782 //                      return;
783 //              }
784                 
785                 /* now build a new listbase from the options selected */
786                 for (i=0, con=const_copy.first; con; i++) {
787                         /* if not selected, free/remove it from the list */
788                         if (!const_toggle[i]) {
789                                 con_back= con->next;
790                                 BLI_freelinkN(&const_copy, con);
791                                 con= con_back;
792                         } 
793                         else
794                                 con= con->next;
795                 }
796                 
797                 /* Copy the temo listbase to the selected posebones */
798                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
799                         if ( (arm->layer & pchan->bone->layer) &&
800                                  (pchan->bone->flag & BONE_SELECTED) &&
801                                  (pchan!=pchanact) ) 
802                         {
803                                 ListBase tmp_constraints = {NULL, NULL};
804                                 
805                                 /* copy constraints to tmpbase and apply 'local' tags before 
806                                  * appending to list of constraints for this channel
807                                  */
808                                 copy_constraints(&tmp_constraints, &const_copy);
809                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
810                                         bConstraint *con;
811                                         
812                                         /* add proxy-local tags */
813                                         for (con= tmp_constraints.first; con; con= con->next)
814                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
815                                 }
816                                 addlisttolist(&pchan->constraints, &tmp_constraints);
817                                 
818                                 /* update flags (need to add here, not just copy) */
819                                 pchan->constflag |= pchanact->constflag;
820                         }
821                 }
822                 BLI_freelistN(&const_copy);
823                 update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
824                 
825                 if (ob->pose)
826                         ob->pose->flag |= POSE_RECALC;
827         }
828         
829         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);   // and all its relations
830         
831         BIF_undo_push("Copy Pose Attributes");
832         
833 }
834
835 /* ******************** copy/paste pose ********************** */
836
837 /* Global copy/paste buffer for pose - cleared on start/end session + before every copy operation */
838 static bPose *g_posebuf = NULL;
839
840 void free_posebuf(void) 
841 {
842         if (g_posebuf) {
843                 /* was copied without constraints */
844                 BLI_freelistN(&g_posebuf->chanbase);
845                 MEM_freeN(g_posebuf);
846         }
847         
848         g_posebuf=NULL;
849 }
850
851 /* ---- */
852
853 static int pose_copy_exec (bContext *C, wmOperator *op)
854 {
855         Object *ob= CTX_data_active_object(C);
856         
857         /* sanity checking */
858         if ELEM(NULL, ob, ob->pose) {
859                 BKE_report(op->reports, RPT_ERROR, "No Pose to Copy");
860                 return OPERATOR_CANCELLED;
861         }
862
863         /* free existing pose buffer */
864         free_posebuf();
865         
866         /* sets chan->flag to POSE_KEY if bone selected, then copy those bones to the buffer */
867         set_pose_keys(ob);  
868         copy_pose(&g_posebuf, ob->pose, 0);
869         
870         
871         return OPERATOR_FINISHED;
872 }
873
874 void POSE_OT_copy (wmOperatorType *ot) 
875 {
876         /* identifiers */
877         ot->name= "Copy Pose";
878         ot->idname= "POSE_OT_copy";
879         ot->description= "Copies the current pose of the selected bones to copy/paste buffer";
880         
881         /* api callbacks */
882         ot->exec= pose_copy_exec;
883         ot->poll= ED_operator_posemode;
884         
885         /* flag */
886         ot->flag= OPTYPE_REGISTER;
887 }
888
889 /* ---- */
890
891 /* Pointers to the builtin KeyingSets that we want to use */
892 static KeyingSet *posePaste_ks_locrotscale = NULL;              /* the only keyingset we'll need */
893
894 /* ---- */
895
896 static int pose_paste_exec (bContext *C, wmOperator *op)
897 {
898         Scene *scene= CTX_data_scene(C);
899         Object *ob= CTX_data_active_object(C);
900         bPoseChannel *chan, *pchan;
901         char name[32];
902         int flip= RNA_boolean_get(op->ptr, "flipped");
903         
904         bCommonKeySrc cks;
905         ListBase dsources = {&cks, &cks};
906         
907         /* init common-key-source for use by KeyingSets */
908         memset(&cks, 0, sizeof(bCommonKeySrc));
909         cks.id= &ob->id;
910         
911         /* sanity checks */
912         if ELEM(NULL, ob, ob->pose)
913                 return OPERATOR_CANCELLED;
914
915         if (g_posebuf == NULL) {
916                 BKE_report(op->reports, RPT_ERROR, "Copy buffer is empty");
917                 return OPERATOR_CANCELLED;
918         }
919         
920         /* Safely merge all of the channels in the buffer pose into any existing pose */
921         for (chan= g_posebuf->chanbase.first; chan; chan=chan->next) {
922                 if (chan->flag & POSE_KEY) {
923                         /* get the name - if flipping, we must flip this first */
924                         BLI_strncpy(name, chan->name, sizeof(name));
925                         if (flip)
926                                 bone_flip_name(name, 0);                /* 0 = don't strip off number extensions */
927                                 
928                         /* only copy when channel exists, poses are not meant to add random channels to anymore */
929                         pchan= get_pose_channel(ob->pose, name);
930                         
931                         if (pchan) {
932                                 /* only loc rot size 
933                                  *      - only copies transform info for the pose 
934                                  */
935                                 VECCOPY(pchan->loc, chan->loc);
936                                 VECCOPY(pchan->size, chan->size);
937                                 pchan->flag= chan->flag;
938                                 
939                                 /* check if rotation modes are compatible (i.e. do they need any conversions) */
940                                 if (pchan->rotmode == chan->rotmode) {
941                                         /* copy the type of rotation in use */
942                                         if (pchan->rotmode > 0) {
943                                                 VECCOPY(pchan->eul, chan->eul);
944                                         }
945                                         else {
946                                                 QUATCOPY(pchan->quat, chan->quat);
947                                         }
948                                 }
949                                 else if (pchan->rotmode > 0) {
950                                         /* quat/axis-angle to euler */
951                                         if (chan->rotmode == ROT_MODE_AXISANGLE)
952                                                 axis_angle_to_eulO( pchan->eul, pchan->rotmode,chan->rotAxis, chan->rotAngle);
953                                         else
954                                                 quat_to_eulO( pchan->eul, pchan->rotmode,chan->quat);
955                                 }
956                                 else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
957                                         /* quat/euler to axis angle */
958                                         if (chan->rotmode > 0)
959                                                 eulO_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,chan->eul, chan->rotmode);
960                                         else    
961                                                 quat_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,chan->quat);
962                                 }
963                                 else {
964                                         /* euler/axis-angle to quat */
965                                         if (chan->rotmode > 0)
966                                                 eulO_to_quat( pchan->quat,chan->eul, chan->rotmode);
967                                         else
968                                                 axis_angle_to_quat(pchan->quat, chan->rotAxis, pchan->rotAngle);
969                                 }
970                                 
971                                 /* paste flipped pose? */
972                                 if (flip) {
973                                         pchan->loc[0]*= -1;
974                                         
975                                         /* has to be done as eulers... */
976                                         if (pchan->rotmode > 0) {
977                                                 pchan->eul[1] *= -1;
978                                                 pchan->eul[2] *= -1;
979                                         }
980                                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
981                                                 float eul[3];
982                                                 
983                                                 axis_angle_to_eulO( eul, EULER_ORDER_DEFAULT,pchan->rotAxis, pchan->rotAngle);
984                                                 eul[1]*= -1;
985                                                 eul[2]*= -1;
986                                                 eulO_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,eul, EULER_ORDER_DEFAULT);
987                                                 
988                                                 // experimental method (uncomment to test):
989 #if 0
990                                                 /* experimental method: just flip the orientation of the axis on x/y axes */
991                                                 pchan->quat[1] *= -1;
992                                                 pchan->quat[2] *= -1;
993 #endif
994                                         }
995                                         else {
996                                                 float eul[3];
997                                                 
998                                                 quat_to_eul( eul,pchan->quat);
999                                                 eul[1]*= -1;
1000                                                 eul[2]*= -1;
1001                                                 eul_to_quat( pchan->quat,eul);
1002                                         }
1003                                 }
1004                                 
1005                                 if (autokeyframe_cfra_can_key(scene, &ob->id)) {
1006                                         /* Set keys on pose
1007                                          *      - KeyingSet to use depends on rotation mode 
1008                                          *      (but that's handled by the templates code)  
1009                                          */
1010                                         // TODO: for getting the KeyingSet used, we should really check which channels were affected
1011                                         if (posePaste_ks_locrotscale == NULL)
1012                                                 posePaste_ks_locrotscale= ANIM_builtin_keyingset_get_named(NULL, "LocRotScale");
1013                                         
1014                                         /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
1015                                         cks.pchan= pchan;
1016                                         
1017                                         modify_keyframes(scene, &dsources, NULL, posePaste_ks_locrotscale, MODIFYKEY_MODE_INSERT, (float)CFRA);
1018                                         
1019                                         /* clear any unkeyed tags */
1020                                         if (chan->bone)
1021                                                 chan->bone->flag &= ~BONE_UNKEYED;
1022                                 }
1023                                 else {
1024                                         /* add unkeyed tags */
1025                                         if (chan->bone)
1026                                                 chan->bone->flag |= BONE_UNKEYED;
1027                                 }
1028                         }
1029                 }
1030         }
1031
1032         /* Update event for pose and deformation children */
1033         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1034         
1035         if (IS_AUTOKEY_ON(scene)) {
1036 // XXX          remake_action_ipos(ob->action);
1037         }
1038         else {
1039                 /* need to trick depgraph, action is not allowed to execute on pose */
1040                 where_is_pose(scene, ob);
1041                 ob->recalc= 0;
1042         }
1043         
1044         /* notifiers for updates */
1045         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1046         WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL); // XXX not really needed, but here for completeness...
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         // NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined...
1236         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) {
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         bPoseChannel *pchan;
1279         short done= 0;
1280         
1281         /* since this call may also be used from the buttons window, we need to check for where to get the object */
1282         if (sa->spacetype == SPACE_BUTS) 
1283                 ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
1284         else
1285                 ob= CTX_data_active_object(C);
1286         
1287         /* only continue if there's an object, and a pose there too */
1288         if (ELEM(NULL, ob, ob->pose))
1289                 return OPERATOR_CANCELLED;
1290         pose= ob->pose;
1291         arm= ob->data;
1292         
1293         /* find selected bones to remove from all bone groups */
1294         // NOTE: unfortunately, we cannot use the context-iterators here, since they might not be defined...
1295         // CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
1296         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1297                 /* ensure that PoseChannel is on visible layer and is not hidden in PoseMode */
1298                 // NOTE: sync this view3d_context() in space_view3d.c
1299                 if ((pchan->bone) && (arm->layer & pchan->bone->layer) && !(pchan->bone->flag & BONE_HIDDEN_P)) {
1300                         if ((pchan->bone->flag & BONE_SELECTED) || (pchan->bone == arm->act_bone)) {
1301                                 if (pchan->agrp_index) {
1302                                         pchan->agrp_index= 0;
1303                                         done= 1;
1304                                 }
1305                         }
1306                 }
1307         }
1308         
1309         /* notifiers for updates */
1310         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1311         
1312         /* report done status */
1313         if (done)
1314                 return OPERATOR_FINISHED;
1315         else
1316                 return OPERATOR_CANCELLED;
1317 }
1318
1319 void POSE_OT_group_unassign (wmOperatorType *ot)
1320 {
1321         /* identifiers */
1322         ot->name= "Remove Selected from Bone Groups";
1323         ot->idname= "POSE_OT_group_unassign";
1324         ot->description= "Remove selected bones from all bone groups";
1325         
1326         /* api callbacks */
1327         ot->exec= pose_group_unassign_exec;
1328         ot->poll= ED_operator_posemode;
1329         
1330         /* flags */
1331         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
1332 }
1333
1334 /* ********************************************** */
1335
1336 static int pose_flip_names_exec (bContext *C, wmOperator *op)
1337 {
1338         Object *ob= CTX_data_active_object(C);
1339         bArmature *arm;
1340         char newname[32];
1341         
1342         /* paranoia checks */
1343         if (ELEM(NULL, ob, ob->pose)) 
1344                 return OPERATOR_CANCELLED;
1345         arm= ob->data;
1346         
1347         /* loop through selected bones, auto-naming them */
1348         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1349         {
1350                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1351                 bone_flip_name(newname, 1);     // 1 = do strip off number extensions
1352                 ED_armature_bone_rename(arm, pchan->name, newname);
1353         }
1354         CTX_DATA_END;
1355         
1356         /* since we renamed stuff... */
1357         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1358
1359         /* note, notifier might evolve */
1360         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1361         
1362         return OPERATOR_FINISHED;
1363 }
1364
1365 void POSE_OT_flip_names (wmOperatorType *ot)
1366 {
1367         /* identifiers */
1368         ot->name= "Flip Names";
1369         ot->idname= "POSE_OT_flip_names";
1370         ot->description= "Flips (and corrects) the names of selected bones";
1371         
1372         /* api callbacks */
1373         ot->exec= pose_flip_names_exec;
1374         ot->poll= ED_operator_posemode;
1375         
1376         /* flags */
1377         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1378 }
1379
1380 /* ------------------ */
1381
1382 static int pose_autoside_names_exec (bContext *C, wmOperator *op)
1383 {
1384         Object *ob= CTX_data_active_object(C);
1385         bArmature *arm;
1386         char newname[32];
1387         short axis= RNA_enum_get(op->ptr, "axis");
1388         
1389         /* paranoia checks */
1390         if (ELEM(NULL, ob, ob->pose)) 
1391                 return OPERATOR_CANCELLED;
1392         arm= ob->data;
1393         
1394         /* loop through selected bones, auto-naming them */
1395         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1396         {
1397                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1398                 bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]);
1399                 ED_armature_bone_rename(arm, pchan->name, newname);
1400         }
1401         CTX_DATA_END;
1402         
1403         /* since we renamed stuff... */
1404         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1405
1406         /* note, notifier might evolve */
1407         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1408         
1409         return OPERATOR_FINISHED;
1410 }
1411
1412 void POSE_OT_autoside_names (wmOperatorType *ot)
1413 {
1414         static EnumPropertyItem axis_items[]= {
1415                 {0, "XAXIS", 0, "X-Axis", "Left/Right"},
1416                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
1417                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
1418                 {0, NULL, 0, NULL, NULL}};
1419         
1420         /* identifiers */
1421         ot->name= "AutoName by Axis";
1422         ot->idname= "POSE_OT_autoside_names";
1423         ot->description= "Automatically renames the selected bones according to which side of the target axis they fall on";
1424         
1425         /* api callbacks */
1426         ot->invoke= WM_menu_invoke;
1427         ot->exec= pose_autoside_names_exec;
1428         ot->poll= ED_operator_posemode;
1429         
1430         /* flags */
1431         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1432         
1433         /* settings */
1434         ot->prop= RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with.");
1435 }
1436
1437 /* ********************************************** */
1438
1439 /* context active object, or weightpainted object with armature in posemode */
1440 void pose_activate_flipped_bone(Scene *scene)
1441 {
1442         Object *ob= OBACT;
1443         bArmature *arm= ob->data;
1444         
1445         if(ob==NULL) return;
1446
1447         if(ob->mode && OB_MODE_WEIGHT_PAINT) {
1448                 ob= modifiers_isDeformedByArmature(ob);
1449         }
1450         if(ob && (ob->mode & OB_MODE_POSE)) {
1451                 bPoseChannel *pchanf;
1452                 
1453                 if(arm->act_bone) {
1454                         char name[32];
1455                         
1456                         BLI_strncpy(name, arm->act_bone->name, 32);
1457                         bone_flip_name(name, 1);        // 0 = do not strip off number extensions
1458                         
1459                         pchanf= get_pose_channel(ob->pose, name);
1460                         if(pchanf && pchanf->bone != arm->act_bone) {
1461                                 arm->act_bone->flag &= ~BONE_SELECTED;
1462                                 pchanf->bone->flag |= BONE_SELECTED;
1463
1464                                 arm->act_bone= pchanf->bone;
1465
1466                                 /* in weightpaint we select the associated vertex group too */
1467                                 if(ob->mode & OB_MODE_WEIGHT_PAINT) {
1468                                         ED_vgroup_select_by_name(OBACT, name);
1469                                         DAG_id_flush_update(&OBACT->id, OB_RECALC_DATA);
1470                                 }
1471                                 
1472                                 // XXX notifiers need to be sent to other editors to update
1473                                 
1474                         }                       
1475                 }
1476         }
1477 }
1478
1479
1480 /* ********************************************** */
1481
1482 /* Present a popup to get the layers that should be used */
1483 static int pose_armature_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1484 {
1485         Object *ob= CTX_data_active_object(C);
1486         bArmature *arm= (ob)? ob->data : NULL;
1487         PointerRNA ptr;
1488         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1489         
1490         /* sanity checking */
1491         if (arm == NULL)
1492                 return OPERATOR_CANCELLED;
1493                 
1494         /* get RNA pointer to armature data to use that to retrieve the layers as ints to init the operator */
1495         RNA_id_pointer_create((ID *)arm, &ptr);
1496         RNA_boolean_get_array(&ptr, "layer", layers);
1497         RNA_boolean_set_array(op->ptr, "layers", layers);
1498         
1499         /* part to sync with other similar operators... */
1500         return WM_operator_props_popup(C, op, evt);
1501 }
1502
1503 /* Set the visible layers for the active armature (edit and pose modes) */
1504 static int pose_armature_layers_exec (bContext *C, wmOperator *op)
1505 {
1506         Object *ob= CTX_data_active_object(C);
1507         bArmature *arm= (ob)? ob->data : NULL;
1508         PointerRNA ptr;
1509         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1510         
1511         /* get the values set in the operator properties */
1512         RNA_boolean_get_array(op->ptr, "layers", layers);
1513         
1514         /* get pointer for armature, and write data there... */
1515         RNA_id_pointer_create((ID *)arm, &ptr);
1516         RNA_boolean_set_array(&ptr, "layer", layers);
1517         
1518         /* note, notifier might evolve */
1519         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1520         
1521         return OPERATOR_FINISHED;
1522 }
1523
1524
1525 void POSE_OT_armature_layers (wmOperatorType *ot)
1526 {
1527         /* identifiers */
1528         ot->name= "Change Armature Layers";
1529         ot->idname= "POSE_OT_armature_layers";
1530         ot->description= "Change the visible armature layers";
1531         
1532         /* callbacks */
1533         ot->invoke= pose_armature_layers_invoke;
1534         ot->exec= pose_armature_layers_exec;
1535         ot->poll= ED_operator_posemode;
1536         
1537         /* flags */
1538         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1539         
1540         /* properties */
1541         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
1542 }
1543
1544 void ARMATURE_OT_armature_layers (wmOperatorType *ot)
1545 {
1546         /* identifiers */
1547         ot->name= "Change Armature Layers";
1548         ot->idname= "ARMATURE_OT_armature_layers";
1549         ot->description= "Change the visible armature layers";
1550         
1551         /* callbacks */
1552         ot->invoke= pose_armature_layers_invoke;
1553         ot->exec= pose_armature_layers_exec;
1554         ot->poll= ED_operator_editarmature;
1555         
1556         /* flags */
1557         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1558         
1559         /* properties */
1560         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
1561 }
1562
1563 /* ------------------- */
1564
1565 /* Present a popup to get the layers that should be used */
1566 static int pose_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1567 {
1568         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1569         
1570         /* get layers that are active already */
1571         memset(&layers, 0, sizeof(layers)); /* set all layers to be off by default */
1572         
1573         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) 
1574         {
1575                 short bit;
1576                 
1577                 /* loop over the bits for this pchan's layers, adding layers where they're needed */
1578                 for (bit= 0; bit < 32; bit++) {
1579                         if (pchan->bone->layer & (1<<bit))
1580                                 layers[bit]= 1;
1581                 }
1582         }
1583         CTX_DATA_END;
1584         
1585         /* copy layers to operator */
1586         RNA_boolean_set_array(op->ptr, "layers", layers);
1587         
1588                 /* part to sync with other similar operators... */
1589         return WM_operator_props_popup(C, op, evt);
1590 }
1591
1592 /* Set the visible layers for the active armature (edit and pose modes) */
1593 static int pose_bone_layers_exec (bContext *C, wmOperator *op)
1594 {
1595         Object *ob= CTX_data_active_object(C);
1596         bArmature *arm= (ob)? ob->data : NULL;
1597         PointerRNA ptr;
1598         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1599         
1600         /* get the values set in the operator properties */
1601         RNA_boolean_get_array(op->ptr, "layers", layers);
1602         
1603         /* set layers of pchans based on the values set in the operator props */
1604         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) 
1605         {
1606                 /* get pointer for pchan, and write flags this way */
1607                 RNA_pointer_create((ID *)arm, &RNA_Bone, pchan->bone, &ptr);
1608                 RNA_boolean_set_array(&ptr, "layer", layers);
1609         }
1610         CTX_DATA_END;
1611         
1612         /* note, notifier might evolve */
1613         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1614         
1615         return OPERATOR_FINISHED;
1616 }
1617
1618 void POSE_OT_bone_layers (wmOperatorType *ot)
1619 {
1620         /* identifiers */
1621         ot->name= "Change Bone Layers";
1622         ot->idname= "POSE_OT_bone_layers";
1623         ot->description= "Change the layers that the selected bones belong to";
1624         
1625         /* callbacks */
1626         ot->invoke= pose_bone_layers_invoke;
1627         ot->exec= pose_bone_layers_exec;
1628         ot->poll= ED_operator_posemode;
1629         
1630         /* flags */
1631         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1632         
1633         /* properties */
1634         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
1635 }
1636
1637 /* ------------------- */
1638
1639 /* Present a popup to get the layers that should be used */
1640 static int armature_bone_layers_invoke (bContext *C, wmOperator *op, wmEvent *evt)
1641 {
1642         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1643         
1644         /* get layers that are active already */
1645         memset(&layers, 0, sizeof(layers)); /* set all layers to be off by default */
1646         
1647         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) 
1648         {
1649                 short bit;
1650                 
1651                 /* loop over the bits for this pchan's layers, adding layers where they're needed */
1652                 for (bit= 0; bit < 32; bit++) {
1653                         if (ebone->layer & (1<<bit))
1654                                 layers[bit]= 1;
1655                 }
1656         }
1657         CTX_DATA_END;
1658         
1659         /* copy layers to operator */
1660         RNA_boolean_set_array(op->ptr, "layers", layers);
1661         
1662                 /* part to sync with other similar operators... */
1663         return WM_operator_props_popup(C, op, evt);
1664 }
1665
1666 /* Set the visible layers for the active armature (edit and pose modes) */
1667 static int armature_bone_layers_exec (bContext *C, wmOperator *op)
1668 {
1669         Object *ob= CTX_data_edit_object(C);
1670         bArmature *arm= (ob)? ob->data : NULL;
1671         PointerRNA ptr;
1672         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
1673         
1674         /* get the values set in the operator properties */
1675         RNA_boolean_get_array(op->ptr, "layers", layers);
1676         
1677         /* set layers of pchans based on the values set in the operator props */
1678         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) 
1679         {
1680                 /* get pointer for pchan, and write flags this way */
1681                 RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr);
1682                 RNA_boolean_set_array(&ptr, "layer", layers);
1683         }
1684         CTX_DATA_END;
1685         
1686         /* note, notifier might evolve */
1687         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
1688         
1689         return OPERATOR_FINISHED;
1690 }
1691
1692 void ARMATURE_OT_bone_layers (wmOperatorType *ot)
1693 {
1694         /* identifiers */
1695         ot->name= "Change Bone Layers";
1696         ot->idname= "ARMATURE_OT_bone_layers";
1697         ot->description= "Change the layers that the selected bones belong to";
1698         
1699         /* callbacks */
1700         ot->invoke= armature_bone_layers_invoke;
1701         ot->exec= armature_bone_layers_exec;
1702         ot->poll= ED_operator_editarmature;
1703         
1704         /* flags */
1705         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1706         
1707         /* properties */
1708         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
1709 }
1710
1711 /* ********************************************** */
1712
1713 static int pose_flip_quats_exec (bContext *C, wmOperator *op)
1714 {
1715         Scene *scene= CTX_data_scene(C);
1716         Object *ob= CTX_data_active_object(C);
1717         
1718         bCommonKeySrc cks;
1719         ListBase dsources = {&cks, &cks};
1720         
1721         /* init common-key-source for use by KeyingSets */
1722         memset(&cks, 0, sizeof(bCommonKeySrc));
1723         cks.id= &ob->id;
1724         
1725         /* loop through all selected pchans, flipping and keying (as needed) */
1726         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones)
1727         {
1728                 /* only if bone is using quaternion rotation */
1729                 if (pchan->rotmode == ROT_MODE_QUAT) {
1730                         /* quaternions have 720 degree range */
1731                         pchan->quat[0]= -pchan->quat[0];
1732                         pchan->quat[1]= -pchan->quat[1];
1733                         pchan->quat[2]= -pchan->quat[2];
1734                         pchan->quat[3]= -pchan->quat[3];
1735                         
1736                         /* perform auto-keying 
1737                          * NOTE: paths don't need recalculation here, since the orientations shouldn't have changed
1738                          */
1739                         if (autokeyframe_cfra_can_key(scene, &ob->id)) {
1740                                 /* Set keys on pose
1741                                  *      - KeyingSet to use depends on rotation mode 
1742                                  *      (but that's handled by the templates code)  
1743                                  */
1744                                 KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
1745                                 
1746                                 /* init cks for this PoseChannel, then use the relative KeyingSets to keyframe it */
1747                                 cks.pchan= pchan;
1748                                 
1749                                 modify_keyframes(scene, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
1750                                 
1751                                 /* clear any unkeyed tags */
1752                                 if (pchan->bone)
1753                                         pchan->bone->flag &= ~BONE_UNKEYED;
1754                         }
1755                         else {
1756                                 /* add unkeyed tags */
1757                                 if (pchan->bone)
1758                                         pchan->bone->flag |= BONE_UNKEYED;
1759                         }
1760                 }
1761         }
1762         CTX_DATA_END;
1763         
1764         /* notifiers and updates */
1765         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1766         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
1767         
1768         return OPERATOR_FINISHED;
1769 }
1770
1771 void POSE_OT_quaternions_flip (wmOperatorType *ot)
1772 {
1773         /* identifiers */
1774         ot->name = "Flip Quats";
1775         ot->idname= "POSE_OT_quaternions_flip";
1776         ot->description= "Flip quaternion values to achieve desired rotations, while maintaining the same orientations";
1777         
1778         /* callbacks */
1779         ot->exec= pose_flip_quats_exec;
1780         ot->poll= ED_operator_posemode;
1781         
1782         /* flags */
1783         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
1784 }
1785
1786 /* ********************************************** */
1787
1788 /* context: active channel */
1789 void pose_special_editmenu(Scene *scene)
1790 {
1791 #if 0
1792         Object *obedit= scene->obedit; // XXX context
1793         Object *ob= OBACT;
1794         short nr;
1795         
1796         /* paranoia checks */
1797         if(!ob && !ob->pose) return;
1798         if(ob==obedit || (ob->mode & OB_MODE_POSE)==0) return;
1799         
1800         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");
1801         if(nr==1) {
1802                 pose_select_constraint_target(scene);
1803         }
1804         else if(nr==2) {
1805                 pose_flip_names();
1806         }
1807         else if(nr==3) {
1808                 pose_calculate_path(C, ob);
1809         }
1810         else if(nr==4) {
1811                 pose_clear_paths(ob);
1812         }
1813         else if(nr==5) {
1814                 pose_clear_user_transforms(scene, ob);
1815         }
1816         else if(nr==6) {
1817                 pose_relax();
1818         }
1819         else if(ELEM3(nr, 7, 8, 9)) {
1820                 pose_autoside_names(nr-7);
1821         }
1822 #endif
1823 }
1824
1825 /* Restore selected pose-bones to 'action'-defined pose */
1826 void pose_clear_user_transforms(Scene *scene, Object *ob)
1827 {
1828         bArmature *arm= ob->data;
1829         bPoseChannel *pchan;
1830         
1831         if (ob->pose == NULL)
1832                 return;
1833         
1834         /* if the object has an action, restore pose to the pose defined by the action by clearing pose on selected bones */
1835         if (ob->action) {
1836                 /* find selected bones */
1837                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1838                         if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1839                                 /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */
1840                                 pchan->bone->flag &= ~BONE_UNKEYED;
1841                         }
1842                 }
1843                 
1844                 /* clear pose locking flag 
1845                  *      - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared
1846                  */
1847                 ob->pose->flag |= POSE_DO_UNLOCK;
1848         }
1849         else {
1850                 /* no action, so restore entire pose to rest pose (cannot restore only selected bones) */
1851                 rest_pose(ob->pose);
1852         }
1853         
1854         DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
1855         BIF_undo_push("Clear User Transform");
1856 }
1857