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