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