4705d1062487a56d73e941c3d9f6d60577707413
[blender.git] / source / blender / editors / armature / pose_edit.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  *                 Reevan McKay (original NaN code)
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  * Pose Mode API's and Operators for Pose Mode armatures
28  */
29
30 /** \file blender/editors/armature/pose_edit.c
31  *  \ingroup edarmature
32  */
33
34 #include "BLI_math.h"
35 #include "BLI_blenlib.h"
36
37 #include "DNA_anim_types.h"
38 #include "DNA_armature_types.h"
39 #include "DNA_constraint_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_object_types.h"
42
43 #include "BKE_anim.h"
44 #include "BKE_action.h"
45 #include "BKE_armature.h"
46 #include "BKE_context.h"
47 #include "BKE_deform.h"
48 #include "BKE_depsgraph.h"
49 #include "BKE_object.h"
50 #include "BKE_report.h"
51
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54 #include "RNA_enum_types.h"
55
56 #include "WM_api.h"
57 #include "WM_types.h"
58
59 #include "ED_armature.h"
60 #include "ED_keyframing.h"
61 #include "ED_screen.h"
62 #include "ED_object.h"
63
64 #include "UI_interface.h"
65
66 #include "armature_intern.h"
67
68 /* matches logic with ED_operator_posemode_context() */
69 Object *ED_pose_object_from_context(bContext *C)
70 {
71         ScrArea *sa = CTX_wm_area(C);
72         Object *ob;
73
74         /* since this call may also be used from the buttons window, we need to check for where to get the object */
75         if (sa && sa->spacetype == SPACE_BUTS) {
76                 ob = ED_object_context(C);
77         }
78         else {
79                 ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
80         }
81
82         return ob;
83 }
84
85 /* This function is used to process the necessary updates for */
86 void ED_armature_enter_posemode(bContext *C, Base *base)
87 {
88         ReportList *reports = CTX_wm_reports(C);
89         Object *ob = base->object;
90         
91         if (ob->id.lib) {
92                 BKE_report(reports, RPT_WARNING, "Cannot pose libdata");
93                 return;
94         }
95         
96         switch (ob->type) {
97                 case OB_ARMATURE:
98                         ob->restore_mode = ob->mode;
99                         ob->mode |= OB_MODE_POSE;
100                         
101                         WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_POSE, NULL);
102                         
103                         break;
104                 default:
105                         return;
106         }
107         
108         /* XXX: disabled as this would otherwise cause a nasty loop... */
109         //ED_object_toggle_modes(C, ob->mode);
110 }
111
112 void ED_armature_exit_posemode(bContext *C, Base *base)
113 {
114         if (base) {
115                 Object *ob = base->object;
116                 
117                 ob->restore_mode = ob->mode;
118                 ob->mode &= ~OB_MODE_POSE;
119                 
120                 WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
121         }
122 }
123
124 /* if a selected or active bone is protected, throw error (oonly if warn == 1) and return 1 */
125 /* only_selected == 1: the active bone is allowed to be protected */
126 #if 0 /* UNUSED 2.5 */
127 static bool pose_has_protected_selected(Object *ob, short warn)
128 {
129         /* check protection */
130         if (ob->proxy) {
131                 bPoseChannel *pchan;
132                 bArmature *arm = ob->data;
133
134                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
135                         if (pchan->bone && (pchan->bone->layer & arm->layer)) {
136                                 if (pchan->bone->layer & arm->layer_protected) {
137                                         if (pchan->bone->flag & BONE_SELECTED)
138                                                 break;
139                                 }
140                         }
141                 }
142                 if (pchan) {
143                         if (warn) error("Cannot change Proxy protected bones");
144                         return 1;
145                 }
146         }
147         return 0;
148 }
149 #endif
150
151 /* ********************************************** */
152 /* Motion Paths */
153
154 /* For the object with pose/action: update paths for those that have got them
155  * This should selectively update paths that exist...
156  *
157  * To be called from various tools that do incremental updates 
158  */
159 void ED_pose_recalculate_paths(Scene *scene, Object *ob)
160 {
161         ListBase targets = {NULL, NULL};
162         
163         /* set flag to force recalc, then grab the relevant bones to target */
164         ob->pose->avs.recalc |= ANIMVIZ_RECALC_PATHS;
165         animviz_get_object_motionpaths(ob, &targets);
166         
167         /* recalculate paths, then free */
168         animviz_calc_motionpaths(scene, &targets);
169         BLI_freelistN(&targets);
170 }
171
172
173 /* show popup to determine settings */
174 static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
175 {       
176         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
177         
178         if (ELEM(NULL, ob, ob->pose))
179                 return OPERATOR_CANCELLED;
180         
181         /* set default settings from existing/stored settings */
182         {
183                 bAnimVizSettings *avs = &ob->pose->avs;
184                 PointerRNA avs_ptr;
185                 
186                 RNA_int_set(op->ptr, "start_frame", avs->path_sf);
187                 RNA_int_set(op->ptr, "end_frame", avs->path_ef);
188                 
189                 RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
190                 RNA_enum_set(op->ptr, "bake_location", RNA_enum_get(&avs_ptr, "bake_location"));
191         }
192         
193         /* show popup dialog to allow editing of range... */
194         // FIXME: hardcoded dimensions here are just arbitrary
195         return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 10 * UI_UNIT_Y);
196 }
197
198 /* For the object with pose/action: create path curves for selected bones 
199  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
200  */
201 static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
202 {
203         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
204         Scene *scene = CTX_data_scene(C);
205         
206         if (ELEM(NULL, ob, ob->pose))
207                 return OPERATOR_CANCELLED;
208         
209         /* grab baking settings from operator settings */
210         {
211                 bAnimVizSettings *avs = &ob->pose->avs;
212                 PointerRNA avs_ptr;
213                 
214                 avs->path_sf = RNA_int_get(op->ptr, "start_frame");
215                 avs->path_ef = RNA_int_get(op->ptr, "end_frame");
216                 
217                 RNA_pointer_create(NULL, &RNA_AnimVizMotionPaths, avs, &avs_ptr);
218                 RNA_enum_set(&avs_ptr, "bake_location", RNA_enum_get(op->ptr, "bake_location"));
219         }
220         
221         /* set up path data for bones being calculated */
222         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
223         {
224                 /* verify makes sure that the selected bone has a bone with the appropriate settings */
225                 animviz_verify_motionpaths(op->reports, scene, ob, pchan);
226         }
227         CTX_DATA_END;
228
229         /* calculate the bones that now have motionpaths... */
230         /* TODO: only make for the selected bones? */
231         ED_pose_recalculate_paths(scene, ob);
232
233         /* notifiers for updates */
234         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
235
236         return OPERATOR_FINISHED; 
237 }
238
239 void POSE_OT_paths_calculate(wmOperatorType *ot)
240 {
241         /* identifiers */
242         ot->name = "Calculate Bone Paths";
243         ot->idname = "POSE_OT_paths_calculate";
244         ot->description = "Calculate paths for the selected bones";
245         
246         /* api callbacks */
247         ot->invoke = pose_calculate_paths_invoke;
248         ot->exec = pose_calculate_paths_exec;
249         ot->poll = ED_operator_posemode_exclusive;
250         
251         /* flags */
252         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
253         
254         /* properties */
255         RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start", 
256                     "First frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
257         RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", 
258                     "Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0);
259         
260         RNA_def_enum(ot->srna, "bake_location", motionpath_bake_location_items, 0, 
261                      "Bake Location", 
262                      "Which point on the bones is used when calculating paths");
263 }
264
265 /* --------- */
266
267 static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
268 {
269         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
270         Scene *scene = CTX_data_scene(C);
271         
272         if (ELEM(NULL, ob, scene))
273                 return OPERATOR_CANCELLED;
274
275         /* calculate the bones that now have motionpaths... */
276         /* TODO: only make for the selected bones? */
277         ED_pose_recalculate_paths(scene, ob);
278         
279         /* notifiers for updates */
280         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
281         
282         return OPERATOR_FINISHED;
283 }
284
285 void POSE_OT_paths_update(wmOperatorType *ot)
286 {
287         /* identifiers */
288         ot->name = "Update Bone Paths";
289         ot->idname = "POSE_OT_paths_update";
290         ot->description = "Recalculate paths for bones that already have them";
291         
292         /* api callbakcs */
293         ot->exec = pose_update_paths_exec;
294         ot->poll = ED_operator_posemode_exclusive; /* TODO: this should probably check for active bone and/or existing paths */
295         
296         /* flags */
297         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
298 }
299
300 /* --------- */
301
302 /* for the object with pose/action: clear path curves for selected bones only */
303 static void ED_pose_clear_paths(Object *ob)
304 {
305         bPoseChannel *pchan;
306         short skipped = 0;
307         
308         if (ELEM(NULL, ob, ob->pose))
309                 return;
310         
311         /* free the motionpath blocks, but also take note of whether we skipped some... */
312         for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
313                 if (pchan->mpath) {
314                         if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
315                                 animviz_free_motionpath(pchan->mpath);
316                                 pchan->mpath = NULL;
317                         }
318                         else 
319                                 skipped = 1;
320                 }
321         }
322         
323         /* if we didn't skip any, we shouldn't have any paths left */
324         if (skipped == 0)
325                 ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS;
326 }
327
328 /* operator callback for this */
329 static int pose_clear_paths_exec(bContext *C, wmOperator *UNUSED(op))
330 {
331         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
332                 
333         /* only continue if there's an object */
334         if (ELEM(NULL, ob, ob->pose))
335                 return OPERATOR_CANCELLED;
336         
337         /* use the backend function for this */
338         ED_pose_clear_paths(ob);
339         
340         /* notifiers for updates */
341         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
342         
343         return OPERATOR_FINISHED; 
344 }
345
346 void POSE_OT_paths_clear(wmOperatorType *ot)
347 {
348         /* identifiers */
349         ot->name = "Clear Bone Paths";
350         ot->idname = "POSE_OT_paths_clear";
351         ot->description = "Clear path caches for selected bones";
352         
353         /* api callbacks */
354         ot->exec = pose_clear_paths_exec;
355         ot->poll = ED_operator_posemode_exclusive;
356         
357         /* flags */
358         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
359 }
360
361 /* ********************************************** */
362 #if 0 /* UNUSED 2.5 */
363 static void pose_copy_menu(Scene *scene)
364 {
365         Object *obedit = scene->obedit; // XXX context
366         Object *ob = OBACT;
367         bArmature *arm;
368         bPoseChannel *pchan, *pchanact;
369         short nr = 0;
370         int i = 0;
371         
372         /* paranoia checks */
373         if (ELEM(NULL, ob, ob->pose)) return;
374         if ((ob == obedit) || (ob->mode & OB_MODE_POSE) == 0) return;
375         
376         pchan = BKE_pose_channel_active(ob);
377         
378         if (pchan == NULL) return;
379         pchanact = pchan;
380         arm = ob->data;
381
382         /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changeable,
383          * but for constraints (just add local constraints)
384          */
385         if (pose_has_protected_selected(ob, 0)) {
386                 i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
387                 if (i < 25)
388                         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");
389                 else
390                         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");
391         }
392         else {
393                 i = BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
394                 if (i < 25)
395                         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");
396                 else
397                         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");
398         }
399         
400         if (nr <= 0) 
401                 return;
402         
403         if (nr != 5) {
404                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
405                         if ((arm->layer & pchan->bone->layer) &&
406                             (pchan->bone->flag & BONE_SELECTED) &&
407                             (pchan != pchanact) )
408                         {
409                                 switch (nr) {
410                                         case 1: /* Local Location */
411                                                 copy_v3_v3(pchan->loc, pchanact->loc);
412                                                 break;
413                                         case 2: /* Local Rotation */
414                                                 copy_qt_qt(pchan->quat, pchanact->quat);
415                                                 copy_v3_v3(pchan->eul, pchanact->eul);
416                                                 break;
417                                         case 3: /* Local Size */
418                                                 copy_v3_v3(pchan->size, pchanact->size);
419                                                 break;
420                                         case 4: /* All Constraints */
421                                         {
422                                                 ListBase tmp_constraints = {NULL, NULL};
423                                                 
424                                                 /* copy constraints to tmpbase and apply 'local' tags before 
425                                                  * appending to list of constraints for this channel
426                                                  */
427                                                 BKE_constraints_copy(&tmp_constraints, &pchanact->constraints, true);
428                                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
429                                                         bConstraint *con;
430                                                         
431                                                         /* add proxy-local tags */
432                                                         for (con = tmp_constraints.first; con; con = con->next)
433                                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
434                                                 }
435                                                 BLI_movelisttolist(&pchan->constraints, &tmp_constraints);
436                                                 
437                                                 /* update flags (need to add here, not just copy) */
438                                                 pchan->constflag |= pchanact->constflag;
439                                                 
440                                                 if (ob->pose)
441                                                         ob->pose->flag |= POSE_RECALC;
442                                         }
443                                         break;
444                                         case 6: /* Transform Locks */
445                                                 pchan->protectflag = pchanact->protectflag;
446                                                 break;
447                                         case 7: /* IK (DOF) settings */
448                                         {
449                                                 pchan->ikflag = pchanact->ikflag;
450                                                 copy_v3_v3(pchan->limitmin, pchanact->limitmin);
451                                                 copy_v3_v3(pchan->limitmax, pchanact->limitmax);
452                                                 copy_v3_v3(pchan->stiffness, pchanact->stiffness);
453                                                 pchan->ikstretch = pchanact->ikstretch;
454                                                 pchan->ikrotweight = pchanact->ikrotweight;
455                                                 pchan->iklinweight = pchanact->iklinweight;
456                                         }
457                                         break;
458                                         case 8: /* Custom Bone Shape */
459                                                 pchan->custom = pchanact->custom;
460                                                 if (pchan->custom) {
461                                                         id_us_plus(&pchan->custom->id);
462                                                 }
463                                                 break;
464                                         case 9: /* Visual Location */
465                                                 BKE_armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
466                                                 break;
467                                         case 10: /* Visual Rotation */
468                                         {
469                                                 float delta_mat[4][4];
470                                                 
471                                                 BKE_armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
472                                                 
473                                                 if (pchan->rotmode == ROT_MODE_AXISANGLE) {
474                                                         float tmp_quat[4];
475                                                         
476                                                         /* need to convert to quat first (in temp var)... */
477                                                         mat4_to_quat(tmp_quat, delta_mat);
478                                                         quat_to_axis_angle(pchan->rotAxis, &pchan->rotAngle, tmp_quat);
479                                                 }
480                                                 else if (pchan->rotmode == ROT_MODE_QUAT)
481                                                         mat4_to_quat(pchan->quat, delta_mat);
482                                                 else
483                                                         mat4_to_eulO(pchan->eul, pchan->rotmode, delta_mat);
484                                         }
485                                         break;
486                                         case 11: /* Visual Size */
487                                         {
488                                                 float delta_mat[4][4], size[4];
489                                                 
490                                                 BKE_armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
491                                                 mat4_to_size(size, delta_mat);
492                                                 copy_v3_v3(pchan->size, size);
493                                         }
494                                 }
495                         }
496                 }
497         }
498         else { /* constraints, optional (note: max we can have is 24 constraints) */
499                 bConstraint *con, *con_back;
500                 int const_toggle[24] = {0}; /* XXX, initialize as 0 to quiet errors */
501                 ListBase const_copy = {NULL, NULL};
502                 
503                 BLI_duplicatelist(&const_copy, &(pchanact->constraints));
504                 
505                 /* build the puplist of constraints */
506                 for (con = pchanact->constraints.first, i = 0; con; con = con->next, i++) {
507                         const_toggle[i] = 1;
508 //                      add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
509                 }
510                 
511 //              if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
512 //                      BLI_freelistN(&const_copy);
513 //                      return;
514 //              }
515                 
516                 /* now build a new listbase from the options selected */
517                 for (i = 0, con = const_copy.first; con; i++) {
518                         /* if not selected, free/remove it from the list */
519                         if (!const_toggle[i]) {
520                                 con_back = con->next;
521                                 BLI_freelinkN(&const_copy, con);
522                                 con = con_back;
523                         }
524                         else
525                                 con = con->next;
526                 }
527                 
528                 /* Copy the temo listbase to the selected posebones */
529                 for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
530                         if ((arm->layer & pchan->bone->layer) &&
531                             (pchan->bone->flag & BONE_SELECTED) &&
532                             (pchan != pchanact) )
533                         {
534                                 ListBase tmp_constraints = {NULL, NULL};
535                                 
536                                 /* copy constraints to tmpbase and apply 'local' tags before 
537                                  * appending to list of constraints for this channel
538                                  */
539                                 BKE_constraints_copy(&tmp_constraints, &const_copy, true);
540                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
541                                         /* add proxy-local tags */
542                                         for (con = tmp_constraints.first; con; con = con->next)
543                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
544                                 }
545                                 BLI_movelisttolist(&pchan->constraints, &tmp_constraints);
546                                 
547                                 /* update flags (need to add here, not just copy) */
548                                 pchan->constflag |= pchanact->constflag;
549                         }
550                 }
551                 BLI_freelistN(&const_copy);
552                 BKE_pose_update_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
553                 
554                 if (ob->pose)
555                         ob->pose->flag |= POSE_RECALC;
556         }
557         
558         DAG_id_tag_update(&ob->id, OB_RECALC_DATA); // and all its relations
559         
560         BIF_undo_push("Copy Pose Attributes");
561         
562 }
563 #endif
564
565 /* ********************************************** */
566
567 static int pose_flip_names_exec(bContext *C, wmOperator *UNUSED(op))
568 {
569         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
570         bArmature *arm;
571         
572         /* paranoia checks */
573         if (ELEM(NULL, ob, ob->pose)) 
574                 return OPERATOR_CANCELLED;
575         arm = ob->data;
576         
577         /* loop through selected bones, auto-naming them */
578         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
579         {
580                 char name_flip[MAXBONENAME];
581                 BKE_deform_flip_side_name(name_flip, pchan->name, true);
582                 ED_armature_bone_rename(arm, pchan->name, name_flip);
583         }
584         CTX_DATA_END;
585         
586         /* since we renamed stuff... */
587         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
588
589         /* note, notifier might evolve */
590         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
591         
592         return OPERATOR_FINISHED;
593 }
594
595 void POSE_OT_flip_names(wmOperatorType *ot)
596 {
597         /* identifiers */
598         ot->name = "Flip Names";
599         ot->idname = "POSE_OT_flip_names";
600         ot->description = "Flips (and corrects) the axis suffixes of the the names of selected bones";
601         
602         /* api callbacks */
603         ot->exec = pose_flip_names_exec;
604         ot->poll = ED_operator_posemode;
605         
606         /* flags */
607         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
608 }
609
610 /* ------------------ */
611
612 static int pose_autoside_names_exec(bContext *C, wmOperator *op)
613 {
614         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
615         bArmature *arm;
616         char newname[MAXBONENAME];
617         short axis = RNA_enum_get(op->ptr, "axis");
618         
619         /* paranoia checks */
620         if (ELEM(NULL, ob, ob->pose)) 
621                 return OPERATOR_CANCELLED;
622         arm = ob->data;
623         
624         /* loop through selected bones, auto-naming them */
625         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
626         {
627                 BLI_strncpy(newname, pchan->name, sizeof(newname));
628                 if (bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]))
629                         ED_armature_bone_rename(arm, pchan->name, newname);
630         }
631         CTX_DATA_END;
632         
633         /* since we renamed stuff... */
634         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
635
636         /* note, notifier might evolve */
637         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
638         
639         return OPERATOR_FINISHED;
640 }
641
642 void POSE_OT_autoside_names(wmOperatorType *ot)
643 {
644         static EnumPropertyItem axis_items[] = {
645                 {0, "XAXIS", 0, "X-Axis", "Left/Right"},
646                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
647                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
648                 {0, NULL, 0, NULL, NULL}
649         };
650         
651         /* identifiers */
652         ot->name = "AutoName by Axis";
653         ot->idname = "POSE_OT_autoside_names";
654         ot->description = "Automatically renames the selected bones according to which side of the target axis they fall on";
655         
656         /* api callbacks */
657         ot->invoke = WM_menu_invoke;
658         ot->exec = pose_autoside_names_exec;
659         ot->poll = ED_operator_posemode;
660         
661         /* flags */
662         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
663         
664         /* settings */
665         ot->prop = RNA_def_enum(ot->srna, "axis", axis_items, 0, "Axis", "Axis tag names with");
666 }
667
668 /* ********************************************** */
669
670 static int pose_bone_rotmode_exec(bContext *C, wmOperator *op)
671 {
672         Object *ob = CTX_data_active_object(C);
673         int mode = RNA_enum_get(op->ptr, "type");
674         
675         /* set rotation mode of selected bones  */
676         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
677         {
678                 pchan->rotmode = mode;
679         }
680         CTX_DATA_END;
681         
682         /* notifiers and updates */
683         DAG_id_tag_update((ID *)ob, OB_RECALC_DATA);
684         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
685         
686         return OPERATOR_FINISHED;
687 }
688
689 void POSE_OT_rotation_mode_set(wmOperatorType *ot)
690 {
691         /* identifiers */
692         ot->name = "Set Rotation Mode";
693         ot->idname = "POSE_OT_rotation_mode_set";
694         ot->description = "Set the rotation representation used by selected bones";
695         
696         /* callbacks */
697         ot->invoke = WM_menu_invoke;
698         ot->exec = pose_bone_rotmode_exec;
699         ot->poll = ED_operator_posemode;
700         
701         /* flags */
702         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
703         
704         /* properties */
705         ot->prop = RNA_def_enum(ot->srna, "type", posebone_rotmode_items, 0, "Rotation Mode", "");
706 }
707
708 /* ********************************************** */
709
710 /* Show all armature layers */
711 static int pose_armature_layers_showall_poll(bContext *C)
712 {
713         /* this single operator can be used in posemode OR editmode for armatures */
714         return ED_operator_posemode(C) || ED_operator_editarmature(C);
715 }
716
717 static int pose_armature_layers_showall_exec(bContext *C, wmOperator *op)
718 {
719         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
720         bArmature *arm = (ob) ? ob->data : NULL;
721         PointerRNA ptr;
722         int maxLayers = (RNA_boolean_get(op->ptr, "all")) ? 32 : 16;
723         int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
724         int i;
725         
726         /* sanity checking */
727         if (arm == NULL)
728                 return OPERATOR_CANCELLED;
729         
730         /* use RNA to set the layers
731          *  although it would be faster to just set directly using bitflags, we still
732          *      need to setup a RNA pointer so that we get the "update" callbacks for free...
733          */
734         RNA_id_pointer_create(&arm->id, &ptr);
735         
736         for (i = 0; i < maxLayers; i++)
737                 layers[i] = 1;
738         
739         RNA_boolean_set_array(&ptr, "layers", layers);
740         
741         /* note, notifier might evolve */
742         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
743         
744         /* done */
745         return OPERATOR_FINISHED;
746 }
747
748 void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
749 {
750         /* identifiers */
751         ot->name = "Show All Layers";
752         ot->idname = "ARMATURE_OT_layers_show_all";
753         ot->description = "Make all armature layers visible";
754         
755         /* callbacks */
756         ot->exec = pose_armature_layers_showall_exec;
757         ot->poll = pose_armature_layers_showall_poll;
758         
759         /* flags */
760         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
761         
762         /* properties */
763         ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All Layers", "Enable all layers or just the first 16 (top row)");
764 }
765
766 /* ------------------- */
767
768 /* Present a popup to get the layers that should be used */
769 static int pose_armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
770 {
771         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
772         bArmature *arm = (ob) ? ob->data : NULL;
773         PointerRNA ptr;
774         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
775         
776         /* sanity checking */
777         if (arm == NULL)
778                 return OPERATOR_CANCELLED;
779                 
780         /* get RNA pointer to armature data to use that to retrieve the layers as ints to init the operator */
781         RNA_id_pointer_create((ID *)arm, &ptr);
782         RNA_boolean_get_array(&ptr, "layers", layers);
783         RNA_boolean_set_array(op->ptr, "layers", layers);
784         
785         /* part to sync with other similar operators... */
786         return WM_operator_props_popup(C, op, event);
787 }
788
789 /* Set the visible layers for the active armature (edit and pose modes) */
790 static int pose_armature_layers_exec(bContext *C, wmOperator *op)
791 {
792         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
793         PointerRNA ptr;
794         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
795
796         if (ELEM(NULL, ob, ob->data)) {
797                 return OPERATOR_CANCELLED;
798         }
799
800         /* get the values set in the operator properties */
801         RNA_boolean_get_array(op->ptr, "layers", layers);
802
803         /* get pointer for armature, and write data there... */
804         RNA_id_pointer_create((ID *)ob->data, &ptr);
805         RNA_boolean_set_array(&ptr, "layers", layers);
806
807         /* note, notifier might evolve */
808         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
809
810         return OPERATOR_FINISHED;
811 }
812
813
814 void POSE_OT_armature_layers(wmOperatorType *ot)
815 {
816         /* identifiers */
817         ot->name = "Change Armature Layers";
818         ot->idname = "POSE_OT_armature_layers";
819         ot->description = "Change the visible armature layers";
820         
821         /* callbacks */
822         ot->invoke = pose_armature_layers_invoke;
823         ot->exec = pose_armature_layers_exec;
824         ot->poll = ED_operator_posemode;
825         
826         /* flags */
827         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
828         
829         /* properties */
830         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
831 }
832
833 void ARMATURE_OT_armature_layers(wmOperatorType *ot)
834 {
835         /* identifiers */
836         ot->name = "Change Armature Layers";
837         ot->idname = "ARMATURE_OT_armature_layers";
838         ot->description = "Change the visible armature layers";
839         
840         /* callbacks */
841         ot->invoke = pose_armature_layers_invoke;
842         ot->exec = pose_armature_layers_exec;
843         ot->poll = ED_operator_editarmature;
844         
845         /* flags */
846         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
847         
848         /* properties */
849         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers to make visible");
850 }
851
852 /* ------------------- */
853
854 /* Present a popup to get the layers that should be used */
855 static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
856 {
857         int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
858         
859         /* get layers that are active already */
860         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
861         {
862                 short bit;
863                 
864                 /* loop over the bits for this pchan's layers, adding layers where they're needed */
865                 for (bit = 0; bit < 32; bit++) {
866                         if (pchan->bone->layer & (1 << bit))
867                                 layers[bit] = 1;
868                 }
869         }
870         CTX_DATA_END;
871         
872         /* copy layers to operator */
873         RNA_boolean_set_array(op->ptr, "layers", layers);
874         
875         /* part to sync with other similar operators... */
876         return WM_operator_props_popup(C, op, event);
877 }
878
879 /* Set the visible layers for the active armature (edit and pose modes) */
880 static int pose_bone_layers_exec(bContext *C, wmOperator *op)
881 {
882         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
883         PointerRNA ptr;
884         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
885
886         if (ob == NULL || ob->data == NULL) {
887                 return OPERATOR_CANCELLED;
888         }
889
890         /* get the values set in the operator properties */
891         RNA_boolean_get_array(op->ptr, "layers", layers);
892
893         /* set layers of pchans based on the values set in the operator props */
894         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
895         {
896                 /* get pointer for pchan, and write flags this way */
897                 RNA_pointer_create((ID *)ob->data, &RNA_Bone, pchan->bone, &ptr);
898                 RNA_boolean_set_array(&ptr, "layers", layers);
899         }
900         CTX_DATA_END;
901
902         /* note, notifier might evolve */
903         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
904
905         return OPERATOR_FINISHED;
906 }
907
908 void POSE_OT_bone_layers(wmOperatorType *ot)
909 {
910         /* identifiers */
911         ot->name = "Change Bone Layers";
912         ot->idname = "POSE_OT_bone_layers";
913         ot->description = "Change the layers that the selected bones belong to";
914         
915         /* callbacks */
916         ot->invoke = pose_bone_layers_invoke;
917         ot->exec = pose_bone_layers_exec;
918         ot->poll = ED_operator_posemode_exclusive;
919         
920         /* flags */
921         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
922         
923         /* properties */
924         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
925 }
926
927 /* ------------------- */
928
929 /* Present a popup to get the layers that should be used */
930 static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
931 {
932         int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
933         
934         /* get layers that are active already */
935         CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones)
936         {
937                 short bit;
938                 
939                 /* loop over the bits for this pchan's layers, adding layers where they're needed */
940                 for (bit = 0; bit < 32; bit++) {
941                         if (ebone->layer & (1 << bit))
942                                 layers[bit] = 1;
943                 }
944         }
945         CTX_DATA_END;
946         
947         /* copy layers to operator */
948         RNA_boolean_set_array(op->ptr, "layers", layers);
949         
950         /* part to sync with other similar operators... */
951         return WM_operator_props_popup(C, op, event);
952 }
953
954 /* Set the visible layers for the active armature (edit and pose modes) */
955 static int armature_bone_layers_exec(bContext *C, wmOperator *op)
956 {
957         Object *ob = CTX_data_edit_object(C);
958         bArmature *arm = (ob) ? ob->data : NULL;
959         PointerRNA ptr;
960         int layers[32]; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
961         
962         /* get the values set in the operator properties */
963         RNA_boolean_get_array(op->ptr, "layers", layers);
964         
965         /* set layers of pchans based on the values set in the operator props */
966         CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones)
967         {
968                 /* get pointer for pchan, and write flags this way */
969                 RNA_pointer_create((ID *)arm, &RNA_EditBone, ebone, &ptr);
970                 RNA_boolean_set_array(&ptr, "layers", layers);
971         }
972         CTX_DATA_END;
973         
974         /* note, notifier might evolve */
975         WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
976         
977         return OPERATOR_FINISHED;
978 }
979
980 void ARMATURE_OT_bone_layers(wmOperatorType *ot)
981 {
982         /* identifiers */
983         ot->name = "Change Bone Layers";
984         ot->idname = "ARMATURE_OT_bone_layers";
985         ot->description = "Change the layers that the selected bones belong to";
986         
987         /* callbacks */
988         ot->invoke = armature_bone_layers_invoke;
989         ot->exec = armature_bone_layers_exec;
990         ot->poll = ED_operator_editarmature;
991         
992         /* flags */
993         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
994         
995         /* properties */
996         RNA_def_boolean_layer_member(ot->srna, "layers", 32, NULL, "Layer", "Armature layers that bone belongs to");
997 }
998
999 /* ********************************************** */
1000 /* Show/Hide Bones */
1001
1002 static int hide_selected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
1003 {
1004         bArmature *arm = ob->data;
1005         
1006         if (arm->layer & bone->layer) {
1007                 if (bone->flag & BONE_SELECTED) {
1008                         bone->flag |= BONE_HIDDEN_P;
1009                         bone->flag &= ~BONE_SELECTED;
1010                         if (arm->act_bone == bone)
1011                                 arm->act_bone = NULL;
1012                 }
1013         }
1014         return 0;
1015 }
1016
1017 static int hide_unselected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
1018 {
1019         bArmature *arm = ob->data;
1020         
1021         if (arm->layer & bone->layer) {
1022                 /* hrm... typo here? */
1023                 if ((bone->flag & BONE_SELECTED) == 0) {
1024                         bone->flag |= BONE_HIDDEN_P;
1025                         if (arm->act_bone == bone)
1026                                 arm->act_bone = NULL;
1027                 }
1028         }
1029         return 0;
1030 }
1031
1032 /* active object is armature in posemode, poll checked */
1033 static int pose_hide_exec(bContext *C, wmOperator *op) 
1034 {
1035         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
1036         bArmature *arm = ob->data;
1037
1038         if (RNA_boolean_get(op->ptr, "unselected"))
1039                 bone_looper(ob, arm->bonebase.first, NULL, hide_unselected_pose_bone_cb);
1040         else
1041                 bone_looper(ob, arm->bonebase.first, NULL, hide_selected_pose_bone_cb);
1042         
1043         /* note, notifier might evolve */
1044         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1045         
1046         return OPERATOR_FINISHED;
1047 }
1048
1049 void POSE_OT_hide(wmOperatorType *ot)
1050 {
1051         /* identifiers */
1052         ot->name = "Hide Selected";
1053         ot->idname = "POSE_OT_hide";
1054         ot->description = "Tag selected bones to not be visible in Pose Mode";
1055         
1056         /* api callbacks */
1057         ot->exec = pose_hide_exec;
1058         ot->poll = ED_operator_posemode;
1059         
1060         /* flags */
1061         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1062         
1063         /* props */
1064         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "");
1065 }
1066
1067 static int show_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
1068 {
1069         bArmature *arm = ob->data;
1070         
1071         if (arm->layer & bone->layer) {
1072                 if (bone->flag & BONE_HIDDEN_P) {
1073                         bone->flag &= ~BONE_HIDDEN_P;
1074                         bone->flag |= BONE_SELECTED;
1075                 }
1076         }
1077         
1078         return 0;
1079 }
1080
1081 /* active object is armature in posemode, poll checked */
1082 static int pose_reveal_exec(bContext *C, wmOperator *UNUSED(op)) 
1083 {
1084         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
1085         bArmature *arm = ob->data;
1086         
1087         bone_looper(ob, arm->bonebase.first, NULL, show_pose_bone_cb);
1088         
1089         /* note, notifier might evolve */
1090         WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
1091
1092         return OPERATOR_FINISHED;
1093 }
1094
1095 void POSE_OT_reveal(wmOperatorType *ot)
1096 {
1097         /* identifiers */
1098         ot->name = "Reveal Selected";
1099         ot->idname = "POSE_OT_reveal";
1100         ot->description = "Unhide all bones that have been tagged to be hidden in Pose Mode";
1101         
1102         /* api callbacks */
1103         ot->exec = pose_reveal_exec;
1104         ot->poll = ED_operator_posemode;
1105         
1106         /* flags */
1107         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1108 }
1109
1110 /* ********************************************** */
1111 /* Flip Quats */
1112
1113 static int pose_flip_quats_exec(bContext *C, wmOperator *UNUSED(op))
1114 {
1115         Scene *scene = CTX_data_scene(C);
1116         Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
1117         KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOC_ROT_SCALE_ID);
1118         
1119         /* loop through all selected pchans, flipping and keying (as needed) */
1120         CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
1121         {
1122                 /* only if bone is using quaternion rotation */
1123                 if (pchan->rotmode == ROT_MODE_QUAT) {
1124                         /* quaternions have 720 degree range */
1125                         negate_v4(pchan->quat);
1126
1127                         ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
1128                 }
1129         }
1130         CTX_DATA_END;
1131         
1132         /* notifiers and updates */
1133         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
1134         WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
1135         
1136         return OPERATOR_FINISHED;
1137 }
1138
1139 void POSE_OT_quaternions_flip(wmOperatorType *ot)
1140 {
1141         /* identifiers */
1142         ot->name = "Flip Quats";
1143         ot->idname = "POSE_OT_quaternions_flip";
1144         ot->description = "Flip quaternion values to achieve desired rotations, while maintaining the same orientations";
1145         
1146         /* callbacks */
1147         ot->exec = pose_flip_quats_exec;
1148         ot->poll = ED_operator_posemode;
1149         
1150         /* flags */
1151         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1152 }
1153