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