2.5 - IK Constraint Tools + Constraint Editing Tweaks
[blender.git] / source / blender / editors / armature / poseobject.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Ton Roosendaal, Blender Foundation '05, full recode.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * support for animation modes - Reevan McKay
27  */
28
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include <string.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_arithb.h"
36 #include "BLI_blenlib.h"
37 #include "BLI_dynstr.h"
38
39 #include "DNA_anim_types.h"
40 #include "DNA_action_types.h"
41 #include "DNA_armature_types.h"
42 #include "DNA_constraint_types.h"
43 #include "DNA_curve_types.h"
44 #include "DNA_mesh_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_modifier_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_screen_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_userdef_types.h"
52
53 #include "BKE_action.h"
54 #include "BKE_armature.h"
55 #include "BKE_blender.h"
56 #include "BKE_context.h"
57 #include "BKE_constraint.h"
58 #include "BKE_deform.h"
59 #include "BKE_depsgraph.h"
60 #include "BKE_displist.h"
61 #include "BKE_fcurve.h"
62 #include "BKE_global.h"
63 #include "BKE_modifier.h"
64 #include "BKE_object.h"
65 #include "BKE_utildefines.h"
66
67 #include "BIF_gl.h"
68
69 #include "RNA_access.h"
70 #include "RNA_define.h"
71
72 #include "WM_api.h"
73 #include "WM_types.h"
74
75 #include "ED_armature.h"
76 #include "ED_anim_api.h"
77 #include "ED_keyframing.h"
78 #include "ED_object.h"
79 #include "ED_mesh.h"
80 #include "ED_screen.h"
81 #include "ED_transform.h" /* for autokey TFM_TRANSLATION, etc */
82 #include "ED_view3d.h"
83
84 #include "armature_intern.h"
85
86 /* ************* XXX *************** */
87 static int movetolayer_short_buts() {return 1;}
88 static int pupmenu() {return 0;}
89 static void waitcursor() {};
90 static void error() {};
91 static void BIF_undo_push() {}
92 static void countall() {}
93 static void autokeyframe_pose_cb_func() {}
94 /* ************* XXX *************** */
95
96 /* This function is used to indicate that a bone is selected and needs keyframes inserted */
97 void set_pose_keys (Object *ob)
98 {
99         bArmature *arm= ob->data;
100         bPoseChannel *chan;
101
102         if (ob->pose){
103                 for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
104                         Bone *bone= chan->bone;
105                         if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
106                                 chan->flag |= POSE_KEY; 
107                         else
108                                 chan->flag &= ~POSE_KEY;
109                 }
110         }
111 }
112
113 /* This function is used to process the necessary updates for */
114 void ED_armature_enter_posemode(bContext *C, Base *base)
115 {
116         Object *ob= base->object;
117         
118         if (ob->id.lib){
119                 error ("Can't pose libdata");
120                 return;
121         }
122         
123         switch (ob->type){
124                 case OB_ARMATURE:
125                         
126                         ob->flag |= OB_POSEMODE;
127                         base->flag= ob->flag;
128                         
129                         WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_POSE, NULL);
130                         
131                         break;
132                 default:
133                         return;
134         }
135         ED_view3d_exit_paint_modes(C);
136 }
137
138 void ED_armature_exit_posemode(bContext *C, Base *base)
139 {
140         if(base) {
141                 Object *ob= base->object;
142                 
143                 ob->flag &= ~OB_POSEMODE;
144                 base->flag= ob->flag;
145                 
146                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
147         }       
148 }
149
150 /* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */
151 /* only_selected==1 : the active bone is allowed to be protected */
152 static short pose_has_protected_selected(Object *ob, short only_selected, short warn)
153 {
154         /* check protection */
155         if (ob->proxy) {
156                 bPoseChannel *pchan;
157                 bArmature *arm= ob->data;
158                 
159                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
160                         if (pchan->bone && (pchan->bone->layer & arm->layer)) {
161                                 if (pchan->bone->layer & arm->layer_protected) {
162                                         if (only_selected && (pchan->bone->flag & BONE_ACTIVE));
163                                         else if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) 
164                                            break;
165                                 }
166                         }
167                 }
168                 if (pchan) {
169                         if (warn) error("Cannot change Proxy protected bones");
170                         return 1;
171                 }
172         }
173         return 0;
174 }
175
176 /* only for real IK, not for auto-IK */
177 int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
178 {
179         bConstraint *con;
180         Bone *bone;
181         
182         /* No need to check if constraint is active (has influence),
183          * since all constraints with CONSTRAINT_IK_AUTO are active */
184         for(con= pchan->constraints.first; con; con= con->next) {
185                 if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
186                         bKinematicConstraint *data= con->data;
187                         if((data->flag & CONSTRAINT_IK_AUTO)==0)
188                                 return 1;
189                 }
190         }
191         for(bone= pchan->bone->childbase.first; bone; bone= bone->next) {
192                 pchan= get_pose_channel(ob->pose, bone->name);
193                 if(pchan && ED_pose_channel_in_IK_chain(ob, pchan))
194                         return 1;
195         }
196         return 0;
197 }
198
199 /* ********************************************** */
200
201 /* For the object with pose/action: create path curves for selected bones 
202  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
203  */
204 void pose_calculate_path(bContext *C, Scene *scene, Object *ob)
205 {
206         bArmature *arm;
207         bPoseChannel *pchan;
208         Base *base;
209         float *fp;
210         int cfra;
211         int sfra, efra;
212         
213         if (ob==NULL || ob->pose==NULL)
214                 return;
215         arm= ob->data;
216         
217         /* version patch for older files here (do_versions patch too complicated) */
218         if ((arm->pathsf == 0) || (arm->pathef == 0)) {
219                 arm->pathsf = SFRA;
220                 arm->pathef = EFRA;
221         }
222         if (arm->pathsize == 0) {
223                 arm->pathsize = 1;
224         }
225         
226         /* set frame values */
227         cfra= CFRA;
228         sfra = arm->pathsf;
229         efra = arm->pathef;
230         if (efra <= sfra) {
231                 error("Can't calculate paths when pathlen <= 0");
232                 return;
233         }
234         
235         waitcursor(1);
236         
237         /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
238         if ((ob->recalc & OB_RECALC)==0) {
239                 ob->recalc |= OB_RECALC;
240                 ED_anim_object_flush_update(C, ob);
241         }
242         else
243                 ED_anim_object_flush_update(C, ob);
244         
245         
246         /* malloc the path blocks */
247         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
248                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
249                         if (arm->layer & pchan->bone->layer) {
250                                 pchan->pathlen= efra-sfra+1;
251                                 pchan->pathsf= sfra;
252                                 pchan->pathef= efra+1;
253                                 if (pchan->path)
254                                         MEM_freeN(pchan->path);
255                                 pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path");
256                         }
257                 }
258         }
259         
260         for (CFRA=sfra; CFRA<=efra; CFRA++) {
261                 /* do all updates */
262                 for (base= FIRSTBASE; base; base= base->next) {
263                         if (base->object->recalc) {
264                                 int temp= base->object->recalc;
265                                 object_handle_update(scene, base->object);
266                                 base->object->recalc= temp;
267                         }
268                 }
269                 
270                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
271                         if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
272                                 if (arm->layer & pchan->bone->layer) {
273                                         if (pchan->path) {
274                                                 fp= pchan->path+3*(CFRA-sfra);
275                                                 
276                                                 if (arm->pathflag & ARM_PATH_HEADS) { 
277                                                         VECCOPY(fp, pchan->pose_head);
278                                                 }
279                                                 else {
280                                                         VECCOPY(fp, pchan->pose_tail);
281                                                 }
282                                                 
283                                                 Mat4MulVecfl(ob->obmat, fp);
284                                         }
285                                 }
286                         }
287                 }
288         }
289         
290         waitcursor(0);
291         
292         CFRA= cfra;
293 }
294
295 /* For the object with pose/action: update paths for those that have got them
296  * This should selectively update paths that exist...
297  */
298 void pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
299 {
300         bArmature *arm;
301         bPoseChannel *pchan;
302         Base *base;
303         float *fp;
304         int cfra;
305         int sfra, efra;
306         
307         if (ob==NULL || ob->pose==NULL)
308                 return;
309         arm= ob->data;
310         
311         /* set frame values */
312         cfra = CFRA;
313         sfra = efra = cfra; 
314         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
315                 if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
316                         if (pchan->path) {
317                                 /* if the pathsf and pathef aren't initialised, abort! */
318                                 if (ELEM(0, pchan->pathsf, pchan->pathef))      
319                                         return;
320                                 
321                                 /* try to increase area to do (only as much as needed) */
322                                 sfra= MIN2(sfra, pchan->pathsf);
323                                 efra= MAX2(efra, pchan->pathef);
324                         }
325                 }
326         }
327         if (efra <= sfra) return;
328         
329         waitcursor(1);
330         
331         /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
332         if ((ob->recalc & OB_RECALC)==0) {
333                 ob->recalc |= OB_RECALC;
334                 ED_anim_object_flush_update(C, ob);
335         }
336         else
337                 ED_anim_object_flush_update(C, ob);
338         
339         for (CFRA=sfra; CFRA<=efra; CFRA++) {
340                 /* do all updates */
341                 for (base= FIRSTBASE; base; base= base->next) {
342                         if (base->object->recalc) {
343                                 int temp= base->object->recalc;
344                                 object_handle_update(scene, base->object);
345                                 base->object->recalc= temp;
346                         }
347                 }
348                 
349                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
350                         if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
351                                 if (pchan->path) {
352                                         /* only update if:
353                                          *      - in range of this pchan's existing path
354                                          *      - ... insert evil filtering/optimising conditions here...
355                                          */
356                                         if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) {
357                                                 fp= pchan->path+3*(CFRA-sfra);
358                                                 
359                                                 if (arm->pathflag & ARM_PATH_HEADS) { 
360                                                         VECCOPY(fp, pchan->pose_head);
361                                                 }
362                                                 else {
363                                                         VECCOPY(fp, pchan->pose_tail);
364                                                 }
365                                                 
366                                                 Mat4MulVecfl(ob->obmat, fp);
367                                         }
368                                 }
369                         }
370                 }
371         }
372         
373         waitcursor(0);
374         
375         CFRA= cfra;
376         ob->pose->flag &= ~POSE_RECALCPATHS;
377 }
378
379 /* for the object with pose/action: clear path curves for selected bones only */
380 void pose_clear_paths(Object *ob)
381 {
382         bPoseChannel *pchan;
383         
384         if (ob==NULL || ob->pose==NULL)
385                 return;
386         
387         /* free the path blocks */
388         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
389                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
390                         if (pchan->path) {
391                                 MEM_freeN(pchan->path);
392                                 pchan->path= NULL;
393                         }
394                 }
395         }
396         
397 }
398
399
400
401 void pose_select_constraint_target(Scene *scene)
402 {
403         Object *obedit= scene->obedit; // XXX context
404         Object *ob= OBACT;
405         bArmature *arm= ob->data;
406         bPoseChannel *pchan;
407         bConstraint *con;
408         
409         /* paranoia checks */
410         if (!ob && !ob->pose) return;
411         if (ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
412         
413         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
414                 if (arm->layer & pchan->bone->layer) {
415                         if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
416                                 for (con= pchan->constraints.first; con; con= con->next) {
417                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
418                                         ListBase targets = {NULL, NULL};
419                                         bConstraintTarget *ct;
420                                         
421                                         if (cti && cti->get_constraint_targets) {
422                                                 cti->get_constraint_targets(con, &targets);
423                                                 
424                                                 for (ct= targets.first; ct; ct= ct->next) {
425                                                         if ((ct->tar == ob) && (ct->subtarget[0])) {
426                                                                 bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
427                                                                 if(pchanc)
428                                                                         pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
429                                                         }
430                                                 }
431                                                 
432                                                 if (cti->flush_constraint_targets)
433                                                         cti->flush_constraint_targets(con, &targets, 1);
434                                         }
435                                 }
436                         }
437                 }
438         }
439         
440         BIF_undo_push("Select constraint target");
441
442 }
443
444 static int pose_select_constraint_target_exec(bContext *C, wmOperator *op)
445 {
446         Object *ob= CTX_data_active_object(C);
447         bArmature *arm= ob->data;
448         bPoseChannel *pchan;
449         bConstraint *con;
450         int found= 0;
451         
452         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
453                 if (arm->layer & pchan->bone->layer) {
454                         if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
455                                 for (con= pchan->constraints.first; con; con= con->next) {
456                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
457                                         ListBase targets = {NULL, NULL};
458                                         bConstraintTarget *ct;
459                                         
460                                         if (cti && cti->get_constraint_targets) {
461                                                 cti->get_constraint_targets(con, &targets);
462                                                 
463                                                 for (ct= targets.first; ct; ct= ct->next) {
464                                                         if ((ct->tar == ob) && (ct->subtarget[0])) {
465                                                                 bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
466                                                                 if(pchanc) {
467                                                                         pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
468                                                                         found= 1;
469                                                                 }
470                                                         }
471                                                 }
472                                                 
473                                                 if (cti->flush_constraint_targets)
474                                                         cti->flush_constraint_targets(con, &targets, 1);
475                                         }
476                                 }
477                         }
478                 }
479         }
480
481         if(!found)
482                 return OPERATOR_CANCELLED;
483
484         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
485
486         return OPERATOR_FINISHED;
487 }
488
489 void POSE_OT_select_constraint_target(wmOperatorType *ot)
490 {
491         /* identifiers */
492         ot->name= "Select Constraint Target";
493         ot->idname= "POSE_OT_select_constraint_target";
494         
495         /* api callbacks */
496         ot->exec= pose_select_constraint_target_exec;
497         ot->poll= ED_operator_posemode;
498         
499         /* flags */
500         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
501 }
502
503 /* ******************* select hierarchy operator ************* */
504
505 static int pose_select_hierarchy_exec(bContext *C, wmOperator *op)
506 {
507         Object *ob= CTX_data_active_object(C);
508         bArmature *arm= ob->data;
509         bPoseChannel *pchan;
510         Bone *curbone, *pabone, *chbone;
511         int direction = RNA_enum_get(op->ptr, "direction");
512         int add_to_sel = RNA_boolean_get(op->ptr, "extend");
513         int found= 0;
514         
515         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
516                 curbone= pchan->bone;
517                 
518                 if (arm->layer & curbone->layer) {
519                         if (curbone->flag & (BONE_ACTIVE)) {
520                                 if (direction == BONE_SELECT_PARENT) {
521                                 
522                                         if (pchan->parent == NULL) continue;
523                                         else pabone= pchan->parent->bone;
524                                         
525                                         if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_P)) {
526                                                 
527                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
528                                                 curbone->flag &= ~BONE_ACTIVE;
529                                                 pabone->flag |= (BONE_ACTIVE|BONE_SELECTED);
530
531                                                 found= 1;
532                                                 break;
533                                         }
534                                 } else { // BONE_SELECT_CHILD
535                                 
536                                         if (pchan->child == NULL) continue;
537                                         else chbone = pchan->child->bone;
538                                         
539                                         if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_P)) {
540                                         
541                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
542                                                 curbone->flag &= ~BONE_ACTIVE;
543                                                 chbone->flag |= (BONE_ACTIVE|BONE_SELECTED);
544
545                                                 found= 1;
546                                                 break;
547                                         }
548                                 }
549                         }
550                 }
551         }
552
553         if(!found)
554                 return OPERATOR_CANCELLED;
555
556         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
557
558         return OPERATOR_FINISHED;
559 }
560
561 void POSE_OT_select_hierarchy(wmOperatorType *ot)
562 {
563         static EnumPropertyItem direction_items[]= {
564         {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
565         {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
566         {0, NULL, 0, NULL, NULL}
567         };
568         
569         /* identifiers */
570         ot->name= "Select Hierarchy";
571         ot->idname= "POSE_OT_select_hierarchy";
572         
573         /* api callbacks */
574         ot->exec= pose_select_hierarchy_exec;
575         ot->poll= ED_operator_posemode;
576         
577         /* flags */
578         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
579         
580         /* props */
581         RNA_def_enum(ot->srna, "direction", direction_items,
582                                  BONE_SELECT_PARENT, "Direction", "");
583         RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
584         
585 }
586
587
588 void pose_copy_menu(Scene *scene)
589 {
590         Object *obedit= scene->obedit; // XXX context
591         Object *ob= OBACT;
592         bArmature *arm= ob->data;
593         bPoseChannel *pchan, *pchanact;
594         short nr=0;
595         int i=0;
596         
597         /* paranoia checks */
598         if (ELEM(NULL, ob, ob->pose)) return;
599         if ((ob==obedit) || (ob->flag & OB_POSEMODE)==0) return;
600         
601         /* find active */
602         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
603                 if (pchan->bone->flag & BONE_ACTIVE) 
604                         break;
605         }
606         
607         if (pchan==NULL) return;
608         pchanact= pchan;
609         
610         /* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable, 
611          * but for constraints (just add local constraints)
612          */
613         if (pose_has_protected_selected(ob, 1, 0)) {
614                 i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
615                 if (i < 25)
616                         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");
617                 else
618                         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");
619         }
620         else {
621                 i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
622                 if (i < 25)
623                         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");
624                 else
625                         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");
626         }
627         
628         if (nr <= 0) 
629                 return;
630         
631         if (nr != 5)  {
632                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
633                         if ( (arm->layer & pchan->bone->layer) &&
634                                  (pchan->bone->flag & BONE_SELECTED) &&
635                                  (pchan != pchanact) ) 
636                         {
637                                 switch (nr) {
638                                         case 1: /* Local Location */
639                                                 VECCOPY(pchan->loc, pchanact->loc);
640                                                 break;
641                                         case 2: /* Local Rotation */
642                                                 QUATCOPY(pchan->quat, pchanact->quat);
643                                                 break;
644                                         case 3: /* Local Size */
645                                                 VECCOPY(pchan->size, pchanact->size);
646                                                 break;
647                                         case 4: /* All Constraints */
648                                         {
649                                                 ListBase tmp_constraints = {NULL, NULL};
650                                                 
651                                                 /* copy constraints to tmpbase and apply 'local' tags before 
652                                                  * appending to list of constraints for this channel
653                                                  */
654                                                 copy_constraints(&tmp_constraints, &pchanact->constraints);
655                                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
656                                                         bConstraint *con;
657                                                         
658                                                         /* add proxy-local tags */
659                                                         for (con= tmp_constraints.first; con; con= con->next)
660                                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
661                                                 }
662                                                 addlisttolist(&pchan->constraints, &tmp_constraints);
663                                                 
664                                                 /* update flags (need to add here, not just copy) */
665                                                 pchan->constflag |= pchanact->constflag;
666                                                 
667                                                 if (ob->pose)
668                                                         ob->pose->flag |= POSE_RECALC;
669                                         }
670                                                 break;
671                                         case 6: /* Transform Locks */
672                                                 pchan->protectflag = pchanact->protectflag;
673                                                 break;
674                                         case 7: /* IK (DOF) settings */
675                                         {
676                                                 pchan->ikflag = pchanact->ikflag;
677                                                 VECCOPY(pchan->limitmin, pchanact->limitmin);
678                                                 VECCOPY(pchan->limitmax, pchanact->limitmax);
679                                                 VECCOPY(pchan->stiffness, pchanact->stiffness);
680                                                 pchan->ikstretch= pchanact->ikstretch;
681                                         }
682                                                 break;
683                                         case 8: /* Custom Bone Shape */
684                                                 pchan->custom = pchanact->custom;
685                                                 break;
686                                         case 9: /* Visual Location */
687                                                 armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
688                                                 break;
689                                         case 10: /* Visual Rotation */
690                                         {
691                                                 float delta_mat[4][4], quat[4];
692                                                 
693                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
694                                                 Mat4ToQuat(delta_mat, quat);
695                                                 QUATCOPY(pchan->quat, quat);
696                                         }
697                                                 break;
698                                         case 11: /* Visual Size */
699                                         {
700                                                 float delta_mat[4][4], size[4];
701                                                 
702                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
703                                                 Mat4ToSize(delta_mat, size);
704                                                 VECCOPY(pchan->size, size);
705                                         }
706                                 }
707                         }
708                 }
709         } 
710         else { /* constraints, optional (note: max we can have is 24 constraints) */
711                 bConstraint *con, *con_back;
712                 int const_toggle[24];
713                 ListBase const_copy = {NULL, NULL};
714                 
715                 BLI_duplicatelist(&const_copy, &(pchanact->constraints));
716                 
717                 /* build the puplist of constraints */
718                 for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){
719                         const_toggle[i]= 1;
720 //                      add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
721                 }
722                 
723 //              if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
724 //                      BLI_freelistN(&const_copy);
725 //                      return;
726 //              }
727                 
728                 /* now build a new listbase from the options selected */
729                 for (i=0, con=const_copy.first; con; i++) {
730                         /* if not selected, free/remove it from the list */
731                         if (!const_toggle[i]) {
732                                 con_back= con->next;
733                                 BLI_freelinkN(&const_copy, con);
734                                 con= con_back;
735                         } 
736                         else
737                                 con= con->next;
738                 }
739                 
740                 /* Copy the temo listbase to the selected posebones */
741                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
742                         if ( (arm->layer & pchan->bone->layer) &&
743                                  (pchan->bone->flag & BONE_SELECTED) &&
744                                  (pchan!=pchanact) ) 
745                         {
746                                 ListBase tmp_constraints = {NULL, NULL};
747                                 
748                                 /* copy constraints to tmpbase and apply 'local' tags before 
749                                  * appending to list of constraints for this channel
750                                  */
751                                 copy_constraints(&tmp_constraints, &const_copy);
752                                 if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
753                                         bConstraint *con;
754                                         
755                                         /* add proxy-local tags */
756                                         for (con= tmp_constraints.first; con; con= con->next)
757                                                 con->flag |= CONSTRAINT_PROXY_LOCAL;
758                                 }
759                                 addlisttolist(&pchan->constraints, &tmp_constraints);
760                                 
761                                 /* update flags (need to add here, not just copy) */
762                                 pchan->constflag |= pchanact->constflag;
763                         }
764                 }
765                 BLI_freelistN(&const_copy);
766                 update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
767                 
768                 if (ob->pose)
769                         ob->pose->flag |= POSE_RECALC;
770         }
771         
772         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);     // and all its relations
773         
774         BIF_undo_push("Copy Pose Attributes");
775         
776 }
777
778 /* ******************** copy/paste pose ********************** */
779
780 static bPose    *g_posebuf=NULL;
781
782 void free_posebuf(void) 
783 {
784         if (g_posebuf) {
785                 // was copied without constraints
786                 BLI_freelistN (&g_posebuf->chanbase);
787                 MEM_freeN (g_posebuf);
788         }
789         g_posebuf=NULL;
790 }
791
792 void copy_posebuf (Scene *scene)
793 {
794         Object *ob= OBACT;
795
796         if (!ob || !ob->pose){
797                 error ("No Pose");
798                 return;
799         }
800
801         free_posebuf();
802         
803         set_pose_keys(ob);  // sets chan->flag to POSE_KEY if bone selected
804         copy_pose(&g_posebuf, ob->pose, 0);
805
806 }
807
808 void paste_posebuf (Scene *scene, int flip)
809 {
810         Object *ob= OBACT;
811         bPoseChannel *chan, *pchan;
812         float eul[4];
813         char name[32];
814         
815         if (!ob || !ob->pose)
816                 return;
817
818         if (!g_posebuf){
819                 error ("Copy buffer is empty");
820                 return;
821         }
822         
823         /*
824         // disabled until protected bones in proxies follow the rules everywhere else!
825         if(pose_has_protected_selected(ob, 1, 1))
826                 return;
827         */
828         
829         /* Safely merge all of the channels in this pose into
830         any existing pose */
831         for (chan=g_posebuf->chanbase.first; chan; chan=chan->next) {
832                 if (chan->flag & POSE_KEY) {
833                         BLI_strncpy(name, chan->name, sizeof(name));
834                         if (flip)
835                                 bone_flip_name (name, 0);               // 0 = don't strip off number extensions
836                                 
837                         /* only copy when channel exists, poses are not meant to add random channels to anymore */
838                         pchan= get_pose_channel(ob->pose, name);
839                         
840                         if (pchan) {
841                                 /* only loc rot size */
842                                 /* only copies transform info for the pose */
843                                 VECCOPY(pchan->loc, chan->loc);
844                                 VECCOPY(pchan->size, chan->size);
845                                 QUATCOPY(pchan->quat, chan->quat);
846                                 pchan->flag= chan->flag;
847                                 
848                                 if (flip) {
849                                         pchan->loc[0]*= -1;
850                                         
851                                         QuatToEul(pchan->quat, eul);
852                                         eul[1]*= -1;
853                                         eul[2]*= -1;
854                                         EulToQuat(eul, pchan->quat);
855                                 }
856                                 
857 #if 0 // XXX old animation system
858                                 if (autokeyframe_cfra_can_key(ob)) {
859                                         ID *id= &ob->id;
860                                         
861                                         /* Set keys on pose */
862                                         if (chan->flag & POSE_ROT) {
863                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
864                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
865                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
866                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
867                                         }
868                                         if (chan->flag & POSE_SIZE) {
869                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
870                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
871                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
872                                         }
873                                         if (chan->flag & POSE_LOC) {
874                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
875                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
876                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
877                                         }
878                                         
879                                         /* clear any unkeyed tags */
880                                         if (chan->bone)
881                                                 chan->bone->flag &= ~BONE_UNKEYED;
882                                 }
883                                 else {
884                                         /* add unkeyed tags */
885                                         if (chan->bone)
886                                                 chan->bone->flag |= BONE_UNKEYED;
887                                 }
888 #endif // XXX old animation system
889                         }
890                 }
891         }
892
893         /* Update event for pose and deformation children */
894         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
895         
896         if (IS_AUTOKEY_ON(scene)) {
897 // XXX          remake_action_ipos(ob->action);
898         }
899         else {
900                 /* need to trick depgraph, action is not allowed to execute on pose */
901                 where_is_pose(scene, ob);
902                 ob->recalc= 0;
903         }
904
905         BIF_undo_push("Paste Action Pose");
906 }
907
908 /* ********************************************** */
909
910 /* context weightpaint and deformer in posemode */
911 void pose_adds_vgroups(Scene *scene, Object *meshobj, int heatweights)
912 {
913 // XXX  extern VPaint Gwp;         /* from vpaint */
914         Object *poseobj= modifiers_isDeformedByArmature(meshobj);
915
916         if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) {
917                 error("The active object must have a deforming armature in pose mode");
918                 return;
919         }
920
921 // XXX  add_verts_to_dgroups(meshobj, poseobj, heatweights, (Gwp.flag & VP_MIRROR_X));
922
923         if(heatweights)
924                 BIF_undo_push("Apply Bone Heat Weights to Vertex Groups");
925         else
926                 BIF_undo_push("Apply Bone Envelopes to Vertex Groups");
927
928         
929         // and all its relations
930         DAG_object_flush_update(scene, meshobj, OB_RECALC_DATA);
931 }
932
933 /* ********************************************** */
934
935 /* adds a new pose-group */
936 void pose_add_posegroup (Scene *scene)
937 {
938         Object *ob= OBACT;
939         bPose *pose= (ob) ? ob->pose : NULL;
940         bActionGroup *grp;
941         
942         if (ELEM(NULL, ob, ob->pose))
943                 return;
944         
945         grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
946         strcpy(grp->name, "Group");
947         BLI_addtail(&pose->agroups, grp);
948         BLI_uniquename(&pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), 32);
949         
950         pose->active_group= BLI_countlist(&pose->agroups);
951         
952         BIF_undo_push("Add Bone Group");
953         
954 }
955
956 /* Remove the active bone-group */
957 void pose_remove_posegroup (Scene *scene)
958 {
959         Object *ob= OBACT;
960         bPose *pose= (ob) ? ob->pose : NULL;
961         bActionGroup *grp = NULL;
962         bPoseChannel *pchan;
963         
964         /* sanity checks */
965         if (ELEM(NULL, ob, pose))
966                 return;
967         if (pose->active_group <= 0)
968                 return;
969         
970         /* get group to remove */
971         grp= BLI_findlink(&pose->agroups, pose->active_group-1);
972         if (grp) {
973                 /* adjust group references (the trouble of using indices!):
974                  *      - firstly, make sure nothing references it 
975                  *      - also, make sure that those after this item get corrected
976                  */
977                 for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
978                         if (pchan->agrp_index == pose->active_group)
979                                 pchan->agrp_index= 0;
980                         else if (pchan->agrp_index > pose->active_group)
981                                 pchan->agrp_index--;
982                 }
983                 
984                 /* now, remove it from the pose */
985                 BLI_freelinkN(&pose->agroups, grp);
986                 pose->active_group= 0;
987                 
988                 BIF_undo_push("Remove Bone Group");
989         }
990         
991 }
992
993 char *build_posegroups_menustr (bPose *pose, short for_pupmenu)
994 {
995         DynStr *pupds= BLI_dynstr_new();
996         bActionGroup *grp;
997         char *str;
998         char buf[16];
999         int i;
1000         
1001         /* add title first (and the "none" entry) */
1002         BLI_dynstr_append(pupds, "Bone Group%t|");
1003         if (for_pupmenu)
1004                 BLI_dynstr_append(pupds, "Add New%x0|");
1005         else
1006                 BLI_dynstr_append(pupds, "BG: [None]%x0|");
1007         
1008         /* loop through groups, adding them */
1009         for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++) {
1010                 if (for_pupmenu == 0)
1011                         BLI_dynstr_append(pupds, "BG: ");
1012                 BLI_dynstr_append(pupds, grp->name);
1013                 
1014                 sprintf(buf, "%%x%d", i);
1015                 BLI_dynstr_append(pupds, buf);
1016                 
1017                 if (grp->next)
1018                         BLI_dynstr_append(pupds, "|");
1019         }
1020         
1021         /* convert to normal MEM_malloc'd string */
1022         str= BLI_dynstr_get_cstring(pupds);
1023         BLI_dynstr_free(pupds);
1024         
1025         return str;
1026 }
1027
1028 /* Assign selected pchans to the bone group that the user selects */
1029 void pose_assign_to_posegroup (Scene *scene, short active)
1030 {
1031         Object *ob= OBACT;
1032         bArmature *arm= (ob) ? ob->data : NULL;
1033         bPose *pose= (ob) ? ob->pose : NULL;
1034         bPoseChannel *pchan;
1035         char *menustr;
1036         int nr;
1037         short done= 0;
1038         
1039         /* sanity checks */
1040         if (ELEM3(NULL, ob, pose, arm))
1041                 return;
1042
1043         /* get group to affect */
1044         if ((active==0) || (pose->active_group <= 0)) {
1045                 menustr= build_posegroups_menustr(pose, 1);
1046                 nr= 0; // XXX pupmenu_col(menustr, 20);
1047                 MEM_freeN(menustr);
1048                 
1049                 if (nr < 0) 
1050                         return;
1051                 else if (nr == 0) {
1052                         /* add new - note: this does an undo push and sets active group */
1053                         pose_add_posegroup(scene);
1054                 }
1055                 else
1056                         pose->active_group= nr;
1057         }
1058         
1059         /* add selected bones to group then */
1060         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1061                 if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1062                         pchan->agrp_index= pose->active_group;
1063                         done= 1;
1064                 }
1065         }
1066         
1067         if (done)
1068                 BIF_undo_push("Add Bones To Group");
1069                 
1070 }
1071
1072 /* Remove selected pchans from their bone groups */
1073 void pose_remove_from_posegroups (Scene *scene)
1074 {
1075         Object *ob= OBACT;
1076         bArmature *arm= (ob) ? ob->data : NULL;
1077         bPose *pose= (ob) ? ob->pose : NULL;
1078         bPoseChannel *pchan;
1079         short done= 0;
1080         
1081         /* sanity checks */
1082         if (ELEM3(NULL, ob, pose, arm))
1083                 return;
1084         
1085         /* remove selected bones from their groups */
1086         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1087                 if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1088                         if (pchan->agrp_index) {
1089                                 pchan->agrp_index= 0;
1090                                 done= 1;
1091                         }
1092                 }
1093         }
1094         
1095         if (done)
1096                 BIF_undo_push("Remove Bones From Groups");
1097                 
1098 }
1099
1100 /* Ctrl-G in 3D-View while in PoseMode */
1101 void pgroup_operation_with_menu (Scene *scene)
1102 {
1103         Object *ob= OBACT;
1104         bArmature *arm= (ob) ? ob->data : NULL;
1105         bPose *pose= (ob) ? ob->pose : NULL;
1106         bPoseChannel *pchan= NULL;
1107         int mode;
1108         
1109         /* sanity checks */
1110         if (ELEM3(NULL, ob, pose, arm))
1111                 return;
1112         
1113         /* check that something is selected */
1114         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1115                 if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) 
1116                         break;
1117         }
1118         if (pchan == NULL)
1119                 return;
1120         
1121         /* get mode of action */
1122         if (pchan)
1123                 mode= pupmenu("Bone Groups%t|Add Selected to Active Group%x1|Add Selected to Group%x2|%|Remove Selected From Groups%x3|Remove Active Group%x4");
1124         else
1125                 mode= pupmenu("Bone Groups%t|Add New Group%x5|Remove Active Group%x4");
1126                 
1127         /* handle mode */
1128         switch (mode) {
1129                 case 1:
1130                         pose_assign_to_posegroup(scene, 1);
1131                         break;
1132                 case 2:
1133                         pose_assign_to_posegroup(scene, 0);
1134                         break;
1135                 case 5:
1136                         pose_add_posegroup(scene);
1137                         break;
1138                 case 3:
1139                         pose_remove_from_posegroups(scene);
1140                         break;
1141                 case 4:
1142                         pose_remove_posegroup(scene);
1143                         break;
1144         }
1145 }
1146
1147 /* ********************************************** */
1148
1149 static short pose_select_same_group (Object *ob)
1150 {
1151         bPose *pose= (ob)? ob->pose : NULL;
1152         bArmature *arm= (ob)? ob->data : NULL;
1153         bPoseChannel *pchan, *chan;
1154         short changed= 0;
1155         
1156         if (ELEM3(NULL, ob, pose, arm))
1157                 return 0;
1158         
1159         /* loop in loop... bad and slow! */
1160         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1161                 if (arm->layer & pchan->bone->layer) {
1162                         if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1163                                 
1164                                 /* only if group matches (and is not selected or current bone) */
1165                                 for (chan= ob->pose->chanbase.first; chan; chan= chan->next) {
1166                                         if (arm->layer & chan->bone->layer) {
1167                                                 if (pchan->agrp_index == chan->agrp_index) {
1168                                                         chan->bone->flag |= BONE_SELECTED;
1169                                                         changed= 1;
1170                                                 }
1171                                         }
1172                                 }
1173                                 
1174                         }
1175                 }
1176         }
1177         
1178         return changed;
1179 }
1180
1181 static short pose_select_same_layer (Object *ob)
1182 {
1183         bPose *pose= (ob)? ob->pose : NULL;
1184         bArmature *arm= (ob)? ob->data : NULL;
1185         bPoseChannel *pchan;
1186         short layers= 0, changed= 0;
1187         
1188         if (ELEM3(NULL, ob, pose, arm))
1189                 return 0;
1190         
1191         /* figure out what bones are selected */
1192         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1193                 if (arm->layer & pchan->bone->layer) {
1194                         if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1195                                 layers |= pchan->bone->layer;
1196                         }
1197                 }
1198         }
1199         if (layers == 0) 
1200                 return 0;
1201                 
1202         /* select bones that are on same layers as layers flag */
1203         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1204                 if (arm->layer & pchan->bone->layer) {
1205                         if (layers & pchan->bone->layer) {
1206                                 pchan->bone->flag |= BONE_SELECTED;
1207                                 changed= 1;
1208                         }
1209                 }
1210         }
1211         
1212         return changed;
1213 }
1214
1215 void pose_select_grouped (Scene *scene, short nr)
1216 {
1217         short changed = 0;
1218         
1219         if (nr == 1)            changed= pose_select_same_group(OBACT);
1220         else if (nr == 2)       changed= pose_select_same_layer(OBACT);
1221         
1222         if (changed) {
1223                 countall();
1224                 BIF_undo_push("Select Grouped");
1225         }
1226 }
1227
1228 /* Shift-G in 3D-View while in PoseMode */
1229 void pose_select_grouped_menu (Scene *scene)
1230 {
1231         short nr;
1232         
1233         /* here we go */
1234         nr= pupmenu("Select Grouped%t|In Same Group%x1|In Same Layer%x2");
1235         pose_select_grouped(scene, nr);
1236 }
1237
1238 /* ********************************************** */
1239
1240 /* context active object */
1241 void pose_flip_names(Scene *scene)
1242 {
1243         Object *obedit= scene->obedit; // XXX context
1244         Object *ob= OBACT;
1245         bArmature *arm= ob->data;
1246         bPoseChannel *pchan;
1247         char newname[32];
1248         
1249         /* paranoia checks */
1250         if(!ob && !ob->pose) return;
1251         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
1252         
1253         if(pose_has_protected_selected(ob, 0, 1))
1254                 return;
1255         
1256         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1257                 if(arm->layer & pchan->bone->layer) {
1258                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1259                                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1260                                 bone_flip_name(newname, 1);     // 1 = do strip off number extensions
1261                                 ED_armature_bone_rename(arm, pchan->name, newname);
1262                         }
1263                 }
1264         }
1265         
1266         BIF_undo_push("Flip names");
1267 }
1268
1269 /* context active object */
1270 void pose_autoside_names(Scene *scene, short axis)
1271 {
1272         Object *obedit= scene->obedit; // XXX context
1273         Object *ob= OBACT;
1274         bArmature *arm= ob->data;
1275         bPoseChannel *pchan;
1276         char newname[32];
1277         
1278         /* paranoia checks */
1279         if (ELEM(NULL, ob, ob->pose)) return;
1280         if (ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
1281         
1282         if (pose_has_protected_selected(ob, 0, 1))
1283                 return;
1284         
1285         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1286                 if(arm->layer & pchan->bone->layer) {
1287                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1288                                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1289                                 bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]);
1290                                 ED_armature_bone_rename(arm, pchan->name, newname);
1291                         }
1292                 }
1293         }
1294         
1295         BIF_undo_push("Flip names");
1296 }
1297
1298 /* context active object, or weightpainted object with armature in posemode */
1299 void pose_activate_flipped_bone(Scene *scene)
1300 {
1301         Object *ob= OBACT;
1302         bArmature *arm= ob->data;
1303         
1304         if(ob==NULL) return;
1305
1306         if(G.f & G_WEIGHTPAINT) {
1307                 ob= modifiers_isDeformedByArmature(ob);
1308         }
1309         if(ob && (ob->flag & OB_POSEMODE)) {
1310                 bPoseChannel *pchan, *pchanf;
1311                 
1312                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1313                         if(arm->layer & pchan->bone->layer) {
1314                                 if(pchan->bone->flag & BONE_ACTIVE)
1315                                         break;
1316                         }
1317                 }
1318                 if(pchan) {
1319                         char name[32];
1320                         
1321                         BLI_strncpy(name, pchan->name, 32);
1322                         bone_flip_name(name, 1);        // 0 = do not strip off number extensions
1323                         
1324                         pchanf= get_pose_channel(ob->pose, name);
1325                         if(pchanf && pchanf!=pchan) {
1326                                 pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
1327                                 pchanf->bone->flag |= (BONE_SELECTED|BONE_ACTIVE);
1328                         
1329                                 /* in weightpaint we select the associated vertex group too */
1330                                 if(G.f & G_WEIGHTPAINT) {
1331                                         vertexgroup_select_by_name(OBACT, name);
1332                                         DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
1333                                 }
1334                                 
1335                                 // XXX notifiers need to be sent to other editors to update
1336                                 
1337                         }                       
1338                 }
1339         }
1340 }
1341
1342 /* This function pops up the move-to-layer popup widgets when the user
1343  * presses either SHIFT-MKEY or MKEY in PoseMode OR EditMode (for Armatures)
1344  */
1345 void pose_movetolayer(Scene *scene)
1346 {
1347         Object *obedit= scene->obedit; // XXX context
1348         Object *ob= OBACT;
1349         bArmature *arm;
1350         short lay= 0;
1351         short shift= 0; // XXX
1352         
1353         if (ob==NULL) return;
1354         arm= ob->data;
1355         
1356         if (shift) {
1357                 /* armature layers */
1358                 lay= arm->layer;
1359                 if ( movetolayer_short_buts(&lay, "Armature Layers")==0 ) return;
1360                 if (lay==0) return;
1361                 arm->layer= lay;
1362                 if(ob->pose)
1363                         ob->pose->proxy_layer= lay;
1364                 
1365         }
1366         else if (obedit) {
1367                 /* the check for editbone layer moving needs to occur before posemode one to work */
1368                 EditBone *ebo;
1369                 EditBone *flipBone;
1370                 
1371                 for (ebo= arm->edbo->first; ebo; ebo= ebo->next) {
1372                         if (arm->layer & ebo->layer) {
1373                                 if (ebo->flag & BONE_SELECTED)
1374                                         lay |= ebo->layer;
1375                         }
1376                 }
1377                 if (lay==0) return;
1378                 
1379                 if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
1380                 if (lay==0) return;
1381                 
1382                 for (ebo= arm->edbo->first; ebo; ebo= ebo->next) {
1383                         if (arm->layer & ebo->layer) {
1384                                 if (ebo->flag & BONE_SELECTED) {
1385                                         ebo->layer= lay;
1386                                         if (arm->flag & ARM_MIRROR_EDIT) {
1387                                                 flipBone = ED_armature_bone_get_mirrored(arm->edbo, ebo);
1388                                                 if (flipBone)
1389                                                         flipBone->layer = lay;
1390                                         }
1391                                 }
1392                         }
1393                 }
1394                 
1395                 BIF_undo_push("Move Bone Layer");
1396         }
1397         else if (ob->flag & OB_POSEMODE) {
1398                 /* pose-channel layers */
1399                 bPoseChannel *pchan;
1400                 
1401                 if (pose_has_protected_selected(ob, 0, 1))
1402                         return;
1403                 
1404                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1405                         if (arm->layer & pchan->bone->layer) {
1406                                 if (pchan->bone->flag & BONE_SELECTED)
1407                                         lay |= pchan->bone->layer;
1408                         }
1409                 }
1410                 if (lay==0) return;
1411                 
1412                 if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
1413                 if (lay==0) return;
1414                 
1415                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1416                         if (arm->layer & pchan->bone->layer) {
1417                                 if (pchan->bone->flag & BONE_SELECTED)
1418                                         pchan->bone->layer= lay;
1419                         }
1420                 }
1421                 
1422                 BIF_undo_push("Move Bone Layer");
1423         }
1424 }
1425
1426 #if 0
1427 // XXX old sys
1428 /* for use with pose_relax only */
1429 static int pose_relax_icu(struct IpoCurve *icu, float framef, float *val, float *frame_prev, float *frame_next)
1430 {
1431         if (!icu) {
1432                 return 0;
1433         } 
1434         else {
1435                 BezTriple *bezt = icu->bezt;
1436                 
1437                 BezTriple *bezt_prev=NULL, *bezt_next=NULL;
1438                 float w1, w2, wtot;
1439                 int i;
1440                 
1441                 for (i=0; i < icu->totvert; i++, bezt++) {
1442                         if (bezt->vec[1][0] < framef - 0.5) {
1443                                 bezt_prev = bezt;
1444                         } else {
1445                                 break;
1446                         }
1447                 }
1448                 
1449                 if (bezt_prev==NULL) return 0;
1450                 
1451                 /* advance to the next, dont need to advance i */
1452                 bezt = bezt_prev+1;
1453                 
1454                 for (; i < icu->totvert; i++, bezt++) {
1455                         if (bezt->vec[1][0] > framef + 0.5) {
1456                                 bezt_next = bezt;
1457                                                 break;
1458                         }
1459                 }
1460                 
1461                 if (bezt_next==NULL) return 0;
1462         
1463                 if (val) {
1464                         w1 = framef - bezt_prev->vec[1][0];
1465                         w2 = bezt_next->vec[1][0] - framef;
1466                         wtot = w1 + w2;
1467                         w1=w1/wtot;
1468                         w2=w2/wtot;
1469 #if 0
1470                         val = (bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1);
1471 #else
1472                         /* apply the value with a hard coded 6th */
1473                         *val = (((bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1)) + (*val * 5.0f)) / 6.0f;
1474 #endif
1475                 }
1476                 
1477                 if (frame_prev) *frame_prev = bezt_prev->vec[1][0];
1478                 if (frame_next) *frame_next = bezt_next->vec[1][0];
1479                 
1480                 return 1;
1481         }
1482 }
1483 #endif
1484
1485 void pose_relax(Scene *scene)
1486 {
1487         Object *ob = OBACT;
1488         bPose *pose;
1489         bAction *act;
1490         bArmature *arm;
1491         
1492 //      IpoCurve *icu_w, *icu_x, *icu_y, *icu_z;
1493         
1494         bPoseChannel *pchan;
1495 //      bActionChannel *achan;
1496 //      float framef = F_CFRA;
1497 //      float frame_prev, frame_next;
1498 //      float quat_prev[4], quat_next[4], quat_interp[4], quat_orig[4];
1499         
1500         int do_scale = 0;
1501         int do_loc = 0;
1502         int do_quat = 0;
1503         int flag = 0;
1504 //      int do_x, do_y, do_z;
1505         
1506         if (!ob) return;
1507         
1508         pose = ob->pose;
1509         act = ob->action;
1510         arm = (bArmature *)ob->data;
1511         
1512         if (!pose || !act || !arm) return;
1513         
1514         for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
1515                 
1516                 pchan->bone->flag &= ~BONE_TRANSFORM;
1517                 
1518                 if (pchan->bone->layer & arm->layer) {
1519                         if (pchan->bone->flag & BONE_SELECTED) {
1520                                 /* do we have an ipo curve? */
1521 #if 0 // XXX old animation system
1522                                 achan= get_action_channel(act, pchan->name);
1523                                 
1524                                 if (achan && achan->ipo) {
1525                                         /*calc_ipo(achan->ipo, ctime);*/
1526                                         
1527                                         do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_X), framef, &pchan->loc[0], NULL, NULL);
1528                                         do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Y), framef, &pchan->loc[1], NULL, NULL);
1529                                         do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Z), framef, &pchan->loc[2], NULL, NULL);
1530                                         do_loc += do_x + do_y + do_z;
1531                                         
1532                                         do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_X), framef, &pchan->size[0], NULL, NULL);
1533                                         do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Y), framef, &pchan->size[1], NULL, NULL);
1534                                         do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Z), framef, &pchan->size[2], NULL, NULL);
1535                                         do_scale += do_x + do_y + do_z;
1536                                                 
1537                                         if(     ((icu_w = find_ipocurve(achan->ipo, AC_QUAT_W))) &&
1538                                                 ((icu_x = find_ipocurve(achan->ipo, AC_QUAT_X))) &&
1539                                                 ((icu_y = find_ipocurve(achan->ipo, AC_QUAT_Y))) &&
1540                                                 ((icu_z = find_ipocurve(achan->ipo, AC_QUAT_Z))) )
1541                                         {
1542                                                 /* use the quatw keyframe as a basis for others */
1543                                                 if (pose_relax_icu(icu_w, framef, NULL, &frame_prev, &frame_next)) {
1544                                                         /* get 2 quats */
1545                                                         quat_prev[0] = eval_icu(icu_w, frame_prev);
1546                                                         quat_prev[1] = eval_icu(icu_x, frame_prev);
1547                                                         quat_prev[2] = eval_icu(icu_y, frame_prev);
1548                                                         quat_prev[3] = eval_icu(icu_z, frame_prev);
1549                                                         
1550                                                         quat_next[0] = eval_icu(icu_w, frame_next);
1551                                                         quat_next[1] = eval_icu(icu_x, frame_next);
1552                                                         quat_next[2] = eval_icu(icu_y, frame_next);
1553                                                         quat_next[3] = eval_icu(icu_z, frame_next);
1554                                                         
1555 #if 0
1556                                                         /* apply the setting, completely smooth */
1557                                                         QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
1558 #else
1559                                                         /* tricky interpolation */
1560                                                         QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
1561                                                         QUATCOPY(quat_orig, pchan->quat);
1562                                                         QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
1563                                                         /* done */
1564 #endif
1565                                                         do_quat++;
1566                                                 }
1567                                         }
1568                                         
1569                                         /* apply BONE_TRANSFORM tag so that autokeying will pick it up */
1570                                         pchan->bone->flag |= BONE_TRANSFORM;
1571                                 }
1572                                 
1573 #endif // XXX old animation system
1574                         }
1575                 }
1576         }
1577         
1578         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
1579         
1580         /* do auto-keying */
1581         if (do_loc)             flag |= TFM_TRANSLATION;
1582         if (do_scale)   flag |= TFM_RESIZE;
1583         if (do_quat)    flag |= TFM_ROTATION;
1584         autokeyframe_pose_cb_func(ob, flag, 0);
1585          
1586         /* clear BONE_TRANSFORM flags */
1587         for (pchan=pose->chanbase.first; pchan; pchan= pchan->next)
1588                 pchan->bone->flag &= ~ BONE_TRANSFORM;
1589         
1590         /* do depsgraph flush */
1591         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1592         BIF_undo_push("Relax Pose");
1593 }
1594
1595 /* for use in insertkey, ensure rotation goes other way around */
1596 void pose_flipquats(Scene *scene)
1597 {
1598         Object *ob = OBACT;
1599         bArmature *arm= ob->data;
1600         bPoseChannel *pchan;
1601         
1602         if(ob->pose==NULL)
1603                 return;
1604         
1605         /* find sel bones */
1606         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1607                 if(pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1608                         /* quaternions have 720 degree range */
1609                         pchan->quat[0]= -pchan->quat[0];
1610                         pchan->quat[1]= -pchan->quat[1];
1611                         pchan->quat[2]= -pchan->quat[2];
1612                         pchan->quat[3]= -pchan->quat[3];
1613                 }
1614         }
1615         
1616         /* do autokey */
1617         autokeyframe_pose_cb_func(ob, TFM_ROTATION, 0);
1618 }
1619
1620 /* context: active channel */
1621 void pose_special_editmenu(Scene *scene)
1622 {
1623 #if 0
1624         Object *obedit= scene->obedit; // XXX context
1625         Object *ob= OBACT;
1626         short nr;
1627         
1628         /* paranoia checks */
1629         if(!ob && !ob->pose) return;
1630         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
1631         
1632         nr= pupmenu("Specials%t|Select Constraint Target%x1|Flip Left-Right Names%x2|Calculate Paths%x3|Clear Paths%x4|Clear User Transform %x5|Relax Pose %x6|%l|AutoName Left-Right%x7|AutoName Front-Back%x8|AutoName Top-Bottom%x9");
1633         if(nr==1) {
1634                 pose_select_constraint_target(scene);
1635         }
1636         else if(nr==2) {
1637                 pose_flip_names();
1638         }
1639         else if(nr==3) {
1640                 pose_calculate_path(C, ob);
1641         }
1642         else if(nr==4) {
1643                 pose_clear_paths(ob);
1644         }
1645         else if(nr==5) {
1646                 pose_clear_user_transforms(scene, ob);
1647         }
1648         else if(nr==6) {
1649                 pose_relax();
1650         }
1651         else if(ELEM3(nr, 7, 8, 9)) {
1652                 pose_autoside_names(nr-7);
1653         }
1654 #endif
1655 }
1656
1657 /* Restore selected pose-bones to 'action'-defined pose */
1658 void pose_clear_user_transforms(Scene *scene, Object *ob)
1659 {
1660         bArmature *arm= ob->data;
1661         bPoseChannel *pchan;
1662         
1663         if (ob->pose == NULL)
1664                 return;
1665         
1666         /* if the object has an action, restore pose to the pose defined by the action by clearing pose on selected bones */
1667         if (ob->action) {
1668                 /* find selected bones */
1669                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1670                         if (pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1671                                 /* just clear the BONE_UNKEYED flag, allowing this bone to get overwritten by actions again */
1672                                 pchan->bone->flag &= ~BONE_UNKEYED;
1673                         }
1674                 }
1675                 
1676                 /* clear pose locking flag 
1677                  *      - this will only clear the user-defined pose in the selected bones, where BONE_UNKEYED has been cleared
1678                  */
1679                 ob->pose->flag |= POSE_DO_UNLOCK;
1680         }
1681         else {
1682                 /* no action, so restore entire pose to rest pose (cannot restore only selected bones) */
1683                 rest_pose(ob->pose);
1684         }
1685         
1686         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1687         BIF_undo_push("Clear User Transform");
1688 }
1689