0b55e4c9a68ede9dcc75970532ed3f290709773a
[blender.git] / source / blender / src / 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 <string.h>
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_arithb.h"
35 #include "BLI_blenlib.h"
36 #include "BLI_dynstr.h"
37
38 #include "DNA_action_types.h"
39 #include "DNA_armature_types.h"
40 #include "DNA_constraint_types.h"
41 #include "DNA_curve_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_modifier_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_view3d_types.h"
49 #include "DNA_userdef_types.h"
50
51 #include "BKE_action.h"
52 #include "BKE_armature.h"
53 #include "BKE_blender.h"
54 #include "BKE_constraint.h"
55 #include "BKE_deform.h"
56 #include "BKE_depsgraph.h"
57 #include "BKE_displist.h"
58 #include "BKE_global.h"
59 #include "BKE_modifier.h"
60 #include "BKE_object.h"
61 #include "BKE_utildefines.h"
62 #include "BKE_ipo.h"
63
64 #include "BIF_editarmature.h"
65 #include "BIF_editaction.h"
66 #include "BIF_editconstraint.h"
67 #include "BIF_editdeform.h"
68 #include "BIF_gl.h"
69 #include "BIF_graphics.h"
70 #include "BIF_interface.h"
71 #include "BIF_poseobject.h"
72 #include "BIF_space.h"
73 #include "BIF_toolbox.h"
74 #include "BIF_screen.h"
75
76 #include "BDR_editobject.h"
77
78 #include "BSE_edit.h"
79 #include "BSE_editipo.h"
80 #include "BSE_trans_types.h"
81
82 #include "mydevice.h"
83 #include "blendef.h"
84 #include "transform.h"
85
86 #include "BIF_transform.h" /* for autokey TFM_TRANSLATION, etc */
87
88 void enter_posemode(void)
89 {
90         Base *base;
91         Object *ob;
92         bArmature *arm;
93         
94         if(G.scene->id.lib) return;
95         base= BASACT;
96         if(base==NULL) return;
97         
98         ob= base->object;
99         
100         if (ob->id.lib){
101                 error ("Can't pose libdata");
102                 return;
103         }
104
105         switch (ob->type){
106         case OB_ARMATURE:
107                 arm= get_armature(ob);
108                 if( arm==NULL ) return;
109                 
110                 ob->flag |= OB_POSEMODE;
111                 base->flag= ob->flag;
112                 
113                 allqueue(REDRAWHEADERS, 0);     
114                 allqueue(REDRAWBUTSALL, 0);     
115                 allqueue(REDRAWOOPS, 0);
116                 allqueue(REDRAWVIEW3D, 0);
117                 break;
118         default:
119                 return;
120         }
121
122         if (G.obedit) exit_editmode(EM_FREEDATA|EM_WAITCURSOR);
123         G.f &= ~(G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT);
124 }
125
126 void set_pose_keys (Object *ob)
127 {
128         bArmature *arm= ob->data;
129         bPoseChannel *chan;
130
131         if (ob->pose){
132                 for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
133                         Bone *bone= chan->bone;
134                         if(bone && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer)) {
135                                 chan->flag |= POSE_KEY;         
136                         }
137                         else {
138                                 chan->flag &= ~POSE_KEY;
139                         }
140                 }
141         }
142 }
143
144
145 void exit_posemode(void)
146 {
147         Object *ob= OBACT;
148         Base *base= BASACT;
149
150         if(ob==NULL) return;
151         
152         ob->flag &= ~OB_POSEMODE;
153         base->flag= ob->flag;
154         
155         countall();
156         allqueue(REDRAWVIEW3D, 0);
157         allqueue(REDRAWOOPS, 0);
158         allqueue(REDRAWHEADERS, 0);     
159         allqueue(REDRAWBUTSALL, 0);     
160
161         scrarea_queue_headredraw(curarea);
162 }
163
164 /* called by buttons to find a bone to display/edit values for */
165 bPoseChannel *get_active_posechannel (Object *ob)
166 {
167         bArmature *arm= ob->data;
168         bPoseChannel *pchan;
169         
170         if ELEM(NULL, ob, ob->pose)
171                 return NULL;
172         
173         /* find active */
174         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
175                 if(pchan->bone && (pchan->bone->flag & BONE_ACTIVE) && (pchan->bone->layer & arm->layer))
176                         return pchan;
177         }
178         
179         return NULL;
180 }
181
182 /* if a selected or active bone is protected, throw error and return 1 */
183 /* only_selected==1 : the active bone is allowed to be protected */
184 static int pose_has_protected_selected(Object *ob, int only_selected)
185 {
186         
187         /* check protection */
188         if(ob->proxy) {
189                 bPoseChannel *pchan;
190                 bArmature *arm= ob->data;
191                 
192                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
193                         if(pchan->bone && (pchan->bone->layer & arm->layer)) {
194                                 if(pchan->bone->layer & arm->layer_protected) {
195                                         if(only_selected && (pchan->bone->flag & BONE_ACTIVE));
196                                         else if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) 
197                                            break;
198                                 }
199                         }
200                 }
201                 if(pchan) {
202                         error("Cannot change Proxy protected bones");
203                         return 1;
204                 }
205         }
206         return 0;
207 }
208
209 /* only for real IK, not for auto-IK */
210 int pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
211 {
212         bConstraint *con;
213         Bone *bone;
214         
215         for(con= pchan->constraints.first; con; con= con->next) {
216                 if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
217                         bKinematicConstraint *data= con->data;
218                         if((data->flag & CONSTRAINT_IK_AUTO)==0)
219                                 return 1;
220                 }
221         }
222         for(bone= pchan->bone->childbase.first; bone; bone= bone->next) {
223                 pchan= get_pose_channel(ob->pose, bone->name);
224                 if(pchan && pose_channel_in_IK_chain(ob, pchan))
225                         return 1;
226         }
227         return 0;
228 }
229
230 /* ********************************************** */
231
232 /* For the object with pose/action: create path curves for selected bones 
233  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
234  */
235 void pose_calculate_path(Object *ob)
236 {
237         bArmature *arm;
238         bPoseChannel *pchan;
239         Base *base;
240         float *fp;
241         int cfra;
242         int sfra, efra;
243         
244         if (ob==NULL || ob->pose==NULL)
245                 return;
246         arm= ob->data;
247         
248         /* version patch for older files here (do_versions patch too complicated) */
249         if ((arm->pathsf == 0) || (arm->pathef == 0)) {
250                 arm->pathsf = SFRA;
251                 arm->pathef = EFRA;
252         }
253         if (arm->pathsize == 0) {
254                 arm->pathsize = 1;
255         }
256         
257         /* set frame values */
258         cfra= CFRA;
259         sfra = arm->pathsf;
260         efra = arm->pathef;
261         if (efra <= sfra) {
262                 error("Can't calculate paths when pathlen <= 0");
263                 return;
264         }
265         
266         waitcursor(1);
267         
268         /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
269         if ((ob->recalc & OB_RECALC)==0) {
270                 ob->recalc |= OB_RECALC;
271                 DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
272         }
273         else
274                 DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
275         
276         
277         /* malloc the path blocks */
278         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
279                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
280                         if (arm->layer & pchan->bone->layer) {
281                                 pchan->pathlen= efra-sfra+1;
282                                 pchan->pathsf= sfra;
283                                 pchan->pathef= efra+1;
284                                 if (pchan->path)
285                                         MEM_freeN(pchan->path);
286                                 pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path");
287                         }
288                 }
289         }
290         
291         for (CFRA=sfra; CFRA<=efra; CFRA++) {
292                 /* do all updates */
293                 for (base= FIRSTBASE; base; base= base->next) {
294                         if (base->object->recalc) {
295                                 int temp= base->object->recalc;
296                                 object_handle_update(base->object);
297                                 base->object->recalc= temp;
298                         }
299                 }
300                 
301                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
302                         if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
303                                 if (arm->layer & pchan->bone->layer) {
304                                         if (pchan->path) {
305                                                 fp= pchan->path+3*(CFRA-sfra);
306                                                 
307                                                 if (arm->pathflag & ARM_PATH_HEADS) { 
308                                                         VECCOPY(fp, pchan->pose_head);
309                                                 }
310                                                 else {
311                                                         VECCOPY(fp, pchan->pose_tail);
312                                                 }
313                                                 
314                                                 Mat4MulVecfl(ob->obmat, fp);
315                                         }
316                                 }
317                         }
318                 }
319         }
320         
321         waitcursor(0);
322         
323         CFRA= cfra;
324         allqueue(REDRAWVIEW3D, 0);      /* recalc tags are still there */
325         allqueue(REDRAWBUTSEDIT, 0);
326 }
327
328 /* For the object with pose/action: update paths for those that have got them
329  * This should selectively update paths that exist...
330  */
331 void pose_recalculate_paths(Object *ob)
332 {
333         bArmature *arm;
334         bPoseChannel *pchan;
335         Base *base;
336         float *fp;
337         int cfra;
338         int sfra, efra;
339         
340         if (ob==NULL || ob->pose==NULL)
341                 return;
342         arm= ob->data;
343         
344         /* set frame values */
345         cfra = CFRA;
346         sfra = efra = cfra; 
347         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
348                 if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
349                         if (pchan->path) {
350                                 /* if the pathsf and pathef aren't initialised, abort! */
351                                 if (ELEM(0, pchan->pathsf, pchan->pathef))      
352                                         return;
353                                 
354                                 /* try to increase area to do (only as much as needed) */
355                                 sfra= MIN2(sfra, pchan->pathsf);
356                                 efra= MAX2(efra, pchan->pathef);
357                         }
358                 }
359         }
360         if (efra <= sfra) return;
361         
362         waitcursor(1);
363         
364         /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
365         if ((ob->recalc & OB_RECALC)==0) {
366                 ob->recalc |= OB_RECALC;
367                 DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
368         }
369         else
370                 DAG_object_update_flags(G.scene, ob, screen_view3d_layers());
371         
372         for (CFRA=sfra; CFRA<=efra; CFRA++) {
373                 /* do all updates */
374                 for (base= FIRSTBASE; base; base= base->next) {
375                         if (base->object->recalc) {
376                                 int temp= base->object->recalc;
377                                 object_handle_update(base->object);
378                                 base->object->recalc= temp;
379                         }
380                 }
381                 
382                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
383                         if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
384                                 if (pchan->path) {
385                                         /* only update if:
386                                          *      - in range of this pchan's existing path
387                                          *      - ... insert evil filtering/optimising conditions here...
388                                          */
389                                         if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) {
390                                                 fp= pchan->path+3*(CFRA-sfra);
391                                                 
392                                                 if (arm->pathflag & ARM_PATH_HEADS) { 
393                                                         VECCOPY(fp, pchan->pose_head);
394                                                 }
395                                                 else {
396                                                         VECCOPY(fp, pchan->pose_tail);
397                                                 }
398                                                 
399                                                 Mat4MulVecfl(ob->obmat, fp);
400                                         }
401                                 }
402                         }
403                 }
404         }
405         
406         waitcursor(0);
407         
408         CFRA= cfra;
409         allqueue(REDRAWVIEW3D, 0);      /* recalc tags are still there */
410         allqueue(REDRAWBUTSEDIT, 0);
411 }
412
413 /* for the object with pose/action: clear path curves for selected bones only */
414 void pose_clear_paths(Object *ob)
415 {
416         bPoseChannel *pchan;
417         
418         if (ob==NULL || ob->pose==NULL)
419                 return;
420         
421         /* free the path blocks */
422         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
423                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
424                         if (pchan->path) {
425                                 MEM_freeN(pchan->path);
426                                 pchan->path= NULL;
427                         }
428                 }
429         }
430         
431         allqueue(REDRAWVIEW3D, 0);
432 }
433
434
435
436 void pose_select_constraint_target(void)
437 {
438         Object *ob= OBACT;
439         bArmature *arm= ob->data;
440         bPoseChannel *pchan;
441         bConstraint *con;
442         
443         /* paranoia checks */
444         if (!ob && !ob->pose) return;
445         if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
446         
447         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
448                 if (arm->layer & pchan->bone->layer) {
449                         if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
450                                 for (con= pchan->constraints.first; con; con= con->next) {
451                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
452                                         ListBase targets = {NULL, NULL};
453                                         bConstraintTarget *ct;
454                                         
455                                         if (cti && cti->get_constraint_targets) {
456                                                 cti->get_constraint_targets(con, &targets);
457                                                 
458                                                 for (ct= targets.first; ct; ct= ct->next) {
459                                                         if ((ct->tar == ob) && (ct->subtarget[0])) {
460                                                                 bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
461                                                                 if(pchanc)
462                                                                         pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
463                                                         }
464                                                 }
465                                                 
466                                                 if (cti->flush_constraint_targets)
467                                                         cti->flush_constraint_targets(con, &targets, 1);
468                                         }
469                                 }
470                         }
471                 }
472         }
473         
474         allqueue (REDRAWVIEW3D, 0);
475         allqueue (REDRAWBUTSOBJECT, 0);
476         allqueue (REDRAWOOPS, 0);
477         
478         BIF_undo_push("Select constraint target");
479
480 }
481
482 /* context: active channel */
483 void pose_special_editmenu(void)
484 {
485         Object *ob= OBACT;
486         short nr;
487         
488         /* paranoia checks */
489         if(!ob && !ob->pose) return;
490         if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
491         
492         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");
493         if(nr==1) {
494                 pose_select_constraint_target();
495         }
496         else if(nr==2) {
497                 pose_flip_names();
498         }
499         else if(nr==3) {
500                 pose_calculate_path(ob);
501         }
502         else if(nr==4) {
503                 pose_clear_paths(ob);
504         }
505         else if(nr==5) {
506                 rest_pose(ob->pose);
507                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
508                 BIF_undo_push("Clear User Transform Pose");
509         }
510         else if(nr==6) {
511                 pose_relax();
512         }
513 }
514
515 void pose_add_IK(void)
516 {
517         Object *ob= OBACT;
518         
519         /* paranoia checks */
520         if(!ob && !ob->pose) return;
521         if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
522         
523         add_constraint(1);      /* 1 means only IK */
524 }
525
526 /* context: all selected channels */
527 void pose_clear_IK(void)
528 {
529         Object *ob= OBACT;
530         bArmature *arm= ob->data;
531         bPoseChannel *pchan;
532         bConstraint *con;
533         bConstraint *next;
534         
535         /* paranoia checks */
536         if(!ob && !ob->pose) return;
537         if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
538         
539         if(pose_has_protected_selected(ob, 0))
540                 return;
541         
542         if(okee("Remove IK constraint(s)")==0) return;
543
544         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
545                 if(arm->layer & pchan->bone->layer) {
546                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
547                                 
548                                 for(con= pchan->constraints.first; con; con= next) {
549                                         next= con->next;
550                                         if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
551                                                 BLI_remlink(&pchan->constraints, con);
552                                                 free_constraint_data(con);
553                                                 MEM_freeN(con);
554                                         }
555                                 }
556                                 pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
557                         }
558                 }
559         }
560         
561         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);   // and all its relations
562         
563         allqueue (REDRAWVIEW3D, 0);
564         allqueue (REDRAWBUTSOBJECT, 0);
565         allqueue (REDRAWOOPS, 0);
566         
567         BIF_undo_push("Remove IK constraint(s)");
568 }
569
570 void pose_clear_constraints(void)
571 {
572         Object *ob= OBACT;
573         bArmature *arm= ob->data;
574         bPoseChannel *pchan;
575         
576         /* paranoia checks */
577         if(!ob && !ob->pose) return;
578         if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
579         
580         if(pose_has_protected_selected(ob, 0))
581                 return;
582         
583         if(okee("Remove Constraints")==0) return;
584         
585         /* find active */
586         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
587                 if(arm->layer & pchan->bone->layer) {
588                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
589                                 free_constraints(&pchan->constraints);
590                                 pchan->constflag= 0;
591                         }
592                 }
593         }
594         
595         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);   // and all its relations
596         
597         allqueue (REDRAWVIEW3D, 0);
598         allqueue (REDRAWBUTSOBJECT, 0);
599         allqueue (REDRAWOOPS, 0);
600         
601         BIF_undo_push("Remove Constraint(s)");
602         
603 }
604
605
606 void pose_copy_menu(void)
607 {
608         Object *ob= OBACT;
609         bArmature *arm= ob->data;
610         bPoseChannel *pchan, *pchanact;
611         short nr;
612         int i=0;
613         
614         /* paranoia checks */
615         if(!ob && !ob->pose) return;
616         if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
617         
618         /* find active */
619         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
620                 if(pchan->bone->flag & BONE_ACTIVE) break;
621         }
622         
623         if(pchan==NULL) return;
624         
625         if(pose_has_protected_selected(ob, 1))
626                 return;
627
628         pchanact= pchan;
629         
630         i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
631         if (i<25)
632                 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");
633         else
634                 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");
635         
636         if(nr==-1) return;
637         if(nr!=5)  {
638                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
639                         if(     (arm->layer & pchan->bone->layer) &&
640                                 (pchan->bone->flag & BONE_SELECTED) &&
641                                 (pchan!=pchanact)
642                         ) {
643                                 switch (nr) {
644                                         case 1: /* Local Location */
645                                                 VECCOPY(pchan->loc, pchanact->loc);
646                                                 break;
647                                         case 2: /* Local Rotation */
648                                                 QUATCOPY(pchan->quat, pchanact->quat);
649                                                 break;
650                                         case 3: /* Local Size */
651                                                 VECCOPY(pchan->size, pchanact->size);
652                                                 break;
653                                         case 4: /* All Constraints */
654                                         {
655                                                 free_constraints(&pchan->constraints);
656                                                 copy_constraints(&pchan->constraints, &pchanact->constraints);
657                                                 pchan->constflag = pchanact->constflag;
658                                         }
659                                                 break;
660                                         case 6: /* Transform Locks */
661                                                 pchan->protectflag = pchanact->protectflag;
662                                                 break;
663                                         case 7: /* IK (DOF) settings */
664                                         {
665                                                 pchan->ikflag = pchanact->ikflag;
666                                                 VECCOPY(pchan->limitmin, pchanact->limitmin);
667                                                 VECCOPY(pchan->limitmax, pchanact->limitmax);
668                                                 VECCOPY(pchan->stiffness, pchanact->stiffness);
669                                                 pchan->ikstretch= pchanact->ikstretch;
670                                         }
671                                                 break;
672                                         case 8: /* Custom Bone Shape */
673                                                 pchan->custom = pchanact->custom;
674                                                 break;
675                                         case 9: /* Visual Location */
676                                                 armature_loc_pose_to_bone(pchan, pchanact->pose_mat[3], pchan->loc);
677                                                 break;
678                                         case 10: /* Visual Rotation */
679                                         {
680                                                 float delta_mat[4][4], quat[4];
681                                                 
682                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
683                                                 Mat4ToQuat(delta_mat, quat);
684                                                 QUATCOPY(pchan->quat, quat);
685                                         }
686                                                 break;
687                                         case 11: /* Visual Size */
688                                         {
689                                                 float delta_mat[4][4], size[4];
690                                                 
691                                                 armature_mat_pose_to_bone(pchan, pchanact->pose_mat, delta_mat);
692                                                 Mat4ToSize(delta_mat, size);
693                                                 VECCOPY(pchan->size, size);
694                                         }
695                                 }
696                         }
697                 }
698         } else { /* constraints, optional */
699                 bConstraint *con, *con_back;
700                 int const_toggle[24];
701                 ListBase const_copy={0, 0};
702                 
703                 duplicatelist (&const_copy, &(pchanact->constraints));
704                 
705                 /* build the puplist of constraints */
706                 for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){
707                         const_toggle[i]= 1;
708                         add_numbut(i, TOG|INT, con->name, 0, 0, &(const_toggle[i]), "");
709                 }
710                 
711                 if (!do_clever_numbuts("Select Constraints", i, REDRAW)) {
712                         BLI_freelistN(&const_copy);
713                         return;
714                 }
715                 
716                 /* now build a new listbase from the options selected */
717                 for (i=0, con=const_copy.first; con; i++) {
718                         if (!const_toggle[i]) {
719                                 con_back= con->next;
720                                 BLI_freelinkN(&const_copy, con);
721                                 con= con_back;
722                         } else {
723                                 con= con->next;
724                         }
725                 }
726                 
727                 /* Copy the temo listbase to the selected posebones */
728                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
729                         if(     (arm->layer & pchan->bone->layer) &&
730                                 (pchan->bone->flag & BONE_SELECTED) &&
731                                 (pchan!=pchanact)
732                         ) {
733                                 free_constraints(&pchan->constraints);
734                                 copy_constraints(&pchan->constraints, &const_copy);
735                                 pchan->constflag = pchanact->constflag;
736                         }
737                 }
738                 BLI_freelistN(&const_copy);
739                 update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
740         }
741         
742         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);   // and all its relations
743         
744         allqueue (REDRAWVIEW3D, 0);
745         allqueue (REDRAWBUTSOBJECT, 0);
746         allqueue (REDRAWOOPS, 0);
747         
748         BIF_undo_push("Copy Pose Attributes");
749         
750 }
751
752 /* ******************** copy/paste pose ********************** */
753
754 static bPose    *g_posebuf=NULL;
755
756 void free_posebuf(void) 
757 {
758         if (g_posebuf) {
759                 // was copied without constraints
760                 BLI_freelistN (&g_posebuf->chanbase);
761                 MEM_freeN (g_posebuf);
762         }
763         g_posebuf=NULL;
764 }
765
766 void copy_posebuf (void)
767 {
768         Object *ob= OBACT;
769
770         if (!ob || !ob->pose){
771                 error ("No Pose");
772                 return;
773         }
774
775         free_posebuf();
776         
777         set_pose_keys(ob);  // sets chan->flag to POSE_KEY if bone selected
778         copy_pose(&g_posebuf, ob->pose, 0);
779
780 }
781
782 void paste_posebuf (int flip)
783 {
784         Object *ob= OBACT;
785         bPoseChannel *chan, *pchan;
786         float eul[4];
787         char name[32];
788         
789         if (!ob || !ob->pose)
790                 return;
791
792         if (!g_posebuf){
793                 error ("Copy buffer is empty");
794                 return;
795         }
796         
797         /*
798         // disabled until protected bones in proxies follow the rules everywhere else!
799         if(pose_has_protected_selected(ob, 1))
800                 return;
801         */
802         
803         /* Safely merge all of the channels in this pose into
804         any existing pose */
805         for (chan=g_posebuf->chanbase.first; chan; chan=chan->next) {
806                 if (chan->flag & POSE_KEY) {
807                         BLI_strncpy(name, chan->name, sizeof(name));
808                         if (flip)
809                                 bone_flip_name (name, 0);               // 0 = don't strip off number extensions
810                                 
811                         /* only copy when channel exists, poses are not meant to add random channels to anymore */
812                         pchan= get_pose_channel(ob->pose, name);
813                         
814                         if (pchan) {
815                                 /* only loc rot size */
816                                 /* only copies transform info for the pose */
817                                 VECCOPY(pchan->loc, chan->loc);
818                                 VECCOPY(pchan->size, chan->size);
819                                 QUATCOPY(pchan->quat, chan->quat);
820                                 pchan->flag= chan->flag;
821                                 
822                                 if (flip) {
823                                         pchan->loc[0]*= -1;
824                                         
825                                         QuatToEul(pchan->quat, eul);
826                                         eul[1]*= -1;
827                                         eul[2]*= -1;
828                                         EulToQuat(eul, pchan->quat);
829                                 }
830                                 
831                                 if (autokeyframe_cfra_can_key(ob)) {
832                                         ID *id= &ob->id;
833                                         
834                                         /* Set keys on pose */
835                                         if (chan->flag & POSE_ROT) {
836                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
837                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
838                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
839                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
840                                         }
841                                         if (chan->flag & POSE_SIZE) {
842                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
843                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
844                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
845                                         }
846                                         if (chan->flag & POSE_LOC) {
847                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
848                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
849                                                 insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
850                                         }
851                                         
852                                         /* clear any unkeyed tags */
853                                         if (chan->bone)
854                                                 chan->bone->flag &= ~BONE_UNKEYED;
855                                 }
856                                 else {
857                                         /* add unkeyed tags */
858                                         if (chan->bone)
859                                                 chan->bone->flag |= BONE_UNKEYED;
860                                 }
861                         }
862                 }
863         }
864
865         /* Update event for pose and deformation children */
866         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
867         
868         if ((IS_AUTOKEY_MODE(NORMAL))) {
869                 remake_action_ipos(ob->action);
870                 allqueue (REDRAWIPO, 0);
871                 allqueue (REDRAWVIEW3D, 0);
872                 allqueue (REDRAWACTION, 0);             
873                 allqueue(REDRAWNLA, 0);
874         }
875         else {
876                 /* need to trick depgraph, action is not allowed to execute on pose */
877                 where_is_pose(ob);
878                 ob->recalc= 0;
879         }
880
881         BIF_undo_push("Paste Action Pose");
882 }
883
884 /* ********************************************** */
885
886 /* context weightpaint and deformer in posemode */
887 void pose_adds_vgroups(Object *meshobj, int heatweights)
888 {
889         extern VPaint Gwp;         /* from vpaint */
890         Object *poseobj= modifiers_isDeformedByArmature(meshobj);
891
892         if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) {
893                 error("The active object must have a deforming armature in pose mode");
894                 return;
895         }
896
897         add_verts_to_dgroups(meshobj, poseobj, heatweights, (Gwp.flag & VP_MIRROR_X));
898
899         if(heatweights)
900                 BIF_undo_push("Apply Bone Heat Weights to Vertex Groups");
901         else
902                 BIF_undo_push("Apply Bone Envelopes to Vertex Groups");
903
904         allqueue(REDRAWVIEW3D, 0);
905         allqueue(REDRAWBUTSEDIT, 0);
906         
907         // and all its relations
908         DAG_object_flush_update(G.scene, meshobj, OB_RECALC_DATA);
909 }
910
911 /* ********************************************** */
912
913 /* adds a new pose-group */
914 void pose_add_posegroup ()
915 {
916         Object *ob= OBACT;
917         bPose *pose= (ob) ? ob->pose : NULL;
918         bActionGroup *grp;
919         
920         if (ELEM(NULL, ob, ob->pose))
921                 return;
922         
923         grp= MEM_callocN(sizeof(bActionGroup), "PoseGroup");
924         strcpy(grp->name, "Group");
925         BLI_addtail(&pose->agroups, grp);
926         BLI_uniquename(&pose->agroups, grp, "Group", offsetof(bActionGroup, name), 32);
927         
928         pose->active_group= BLI_countlist(&pose->agroups);
929         
930         BIF_undo_push("Add Bone Group");
931         
932         allqueue(REDRAWBUTSEDIT, 0);
933         allqueue(REDRAWVIEW3D, 0);
934 }
935
936 /* Remove the active bone-group */
937 void pose_remove_posegroup ()
938 {
939         Object *ob= OBACT;
940         bPose *pose= (ob) ? ob->pose : NULL;
941         bActionGroup *grp = NULL;
942         bPoseChannel *pchan;
943         
944         /* sanity checks */
945         if (ELEM(NULL, ob, pose))
946                 return;
947         if (pose->active_group <= 0)
948                 return;
949         
950         /* get group to remove */
951         grp= BLI_findlink(&pose->agroups, pose->active_group-1);
952         if (grp) {
953                 /* firstly, make sure nothing references it */
954                 for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
955                         if (pchan->agrp_index == pose->active_group)
956                                 pchan->agrp_index= 0;
957                 }
958                 
959                 /* now, remove it from the pose */
960                 BLI_freelinkN(&pose->agroups, grp);
961                 pose->active_group= 0;
962                 
963                 BIF_undo_push("Remove Bone Group");
964         }
965         
966         allqueue(REDRAWBUTSEDIT, 0);
967         allqueue(REDRAWVIEW3D, 0);
968 }
969
970 char *build_posegroups_menustr (bPose *pose, short for_pupmenu)
971 {
972         DynStr *pupds= BLI_dynstr_new();
973         bActionGroup *grp;
974         char *str;
975         char buf[16];
976         int i;
977         
978         /* add title first (and the "none" entry) */
979         BLI_dynstr_append(pupds, "Bone Group%t|");
980         if (for_pupmenu)
981                 BLI_dynstr_append(pupds, "Add New%x0|");
982         else
983                 BLI_dynstr_append(pupds, "BG: [None]%x0|");
984         
985         /* loop through markers, adding them */
986         for (grp= pose->agroups.first, i=1; grp; grp=grp->next, i++) {
987                 if (for_pupmenu == 0)
988                         BLI_dynstr_append(pupds, "BG: ");
989                 BLI_dynstr_append(pupds, grp->name);
990                 
991                 sprintf(buf, "%%x%d", i);
992                 BLI_dynstr_append(pupds, buf);
993                 
994                 if (grp->next)
995                         BLI_dynstr_append(pupds, "|");
996         }
997         
998         /* convert to normal MEM_malloc'd string */
999         str= BLI_dynstr_get_cstring(pupds);
1000         BLI_dynstr_free(pupds);
1001         
1002         return str;
1003 }
1004
1005 /* Assign selected pchans to the bone group that the user selects */
1006 void pose_assign_to_posegroup ()
1007 {
1008         Object *ob= OBACT;
1009         bArmature *arm= (ob) ? ob->data : NULL;
1010         bPose *pose= (ob) ? ob->pose : NULL;
1011         bPoseChannel *pchan;
1012         char *menustr;
1013         int nr;
1014         short done= 0;
1015         
1016         /* sanity checks */
1017         if (ELEM3(NULL, ob, pose, arm))
1018                 return;
1019
1020         /* get group to affect */
1021         menustr= build_posegroups_menustr(pose, 1);
1022         nr= pupmenu(menustr);
1023         MEM_freeN(menustr);
1024         
1025         if (nr < 0) 
1026                 return;
1027         else if (nr == 0) {
1028                 /* add new - note: this does an undo push and sets active group */
1029                 pose_add_posegroup();
1030         }
1031         else
1032                 pose->active_group= nr;
1033         
1034         /* add selected bones to group then */
1035         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1036                 if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1037                         pchan->agrp_index= pose->active_group;
1038                         done= 1;
1039                 }
1040         }
1041         
1042         if (done)
1043                 BIF_undo_push("Add Bones To Group");
1044                 
1045         allqueue(REDRAWBUTSEDIT, 0);
1046         allqueue(REDRAWVIEW3D, 0);
1047 }
1048
1049 /* Remove selected pchans from their bone groups */
1050 void pose_remove_from_posegroups ()
1051 {
1052         Object *ob= OBACT;
1053         bArmature *arm= (ob) ? ob->data : NULL;
1054         bPose *pose= (ob) ? ob->pose : NULL;
1055         bPoseChannel *pchan;
1056         short done= 0;
1057         
1058         /* sanity checks */
1059         if (ELEM3(NULL, ob, pose, arm))
1060                 return;
1061         
1062         /* remove selected bones from their groups */
1063         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1064                 if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1065                         if (pchan->agrp_index) {
1066                                 pchan->agrp_index= 0;
1067                                 done= 1;
1068                         }
1069                 }
1070         }
1071         
1072         if (done)
1073                 BIF_undo_push("Remove Bones From Groups");
1074                 
1075         allqueue(REDRAWBUTSEDIT, 0);
1076         allqueue(REDRAWVIEW3D, 0);
1077 }
1078
1079 /* Ctrl-G in 3D-View while in PoseMode */
1080 void pgroup_operation_with_menu (void)
1081 {
1082         Object *ob= OBACT;
1083         bArmature *arm= (ob) ? ob->data : NULL;
1084         bPose *pose= (ob) ? ob->pose : NULL;
1085         bPoseChannel *pchan= NULL;
1086         int mode;
1087         
1088         /* sanity checks */
1089         if (ELEM3(NULL, ob, pose, arm))
1090                 return;
1091         
1092         /* check that something is selected */
1093         for (pchan= pose->chanbase.first; pchan; pchan= pchan->next) {
1094                 if ((pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) 
1095                         break;
1096         }
1097         if (pchan == NULL)
1098                 return;
1099         
1100         /* get mode of action */
1101         if (pchan)
1102                 mode= pupmenu("Bone Groups%t|Add Selected to Group%x1|Add New Group%x2|Remove Selected From Groups%x3|Remove Active Group%x4");
1103         else
1104                 mode= pupmenu("Bone Groups%t|Add New Group%x2|Remove Active Group%x4");
1105                 
1106         /* handle mode */
1107         switch (mode) {
1108                 case 1:
1109                         pose_assign_to_posegroup();
1110                         break;
1111                 case 2:
1112                         pose_add_posegroup();
1113                         break;
1114                 case 3:
1115                         pose_remove_from_posegroups();
1116                         break;
1117                 case 4:
1118                         pose_remove_posegroup();
1119                         break;
1120         }
1121 }
1122
1123 /* ********************************************** */
1124
1125 /* context active object */
1126 void pose_flip_names(void)
1127 {
1128         Object *ob= OBACT;
1129         bArmature *arm= ob->data;
1130         bPoseChannel *pchan;
1131         char newname[32];
1132         
1133         /* paranoia checks */
1134         if(!ob && !ob->pose) return;
1135         if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
1136         
1137         if(pose_has_protected_selected(ob, 0))
1138                 return;
1139         
1140         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1141                 if(arm->layer & pchan->bone->layer) {
1142                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1143                                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1144                                 bone_flip_name(newname, 1);     // 1 = do strip off number extensions
1145                                 armature_bone_rename(ob->data, pchan->name, newname);
1146                         }
1147                 }
1148         }
1149         
1150         allqueue(REDRAWVIEW3D, 0);
1151         allqueue(REDRAWBUTSEDIT, 0);
1152         allqueue(REDRAWBUTSOBJECT, 0);
1153         allqueue (REDRAWACTION, 0);
1154         allqueue(REDRAWOOPS, 0);
1155         BIF_undo_push("Flip names");
1156         
1157 }
1158
1159 /* context active object, or weightpainted object with armature in posemode */
1160 void pose_activate_flipped_bone(void)
1161 {
1162         Object *ob= OBACT;
1163         bArmature *arm= ob->data;
1164         
1165         if(ob==NULL) return;
1166
1167         if(G.f & G_WEIGHTPAINT) {
1168                 ob= modifiers_isDeformedByArmature(ob);
1169         }
1170         if(ob && (ob->flag & OB_POSEMODE)) {
1171                 bPoseChannel *pchan, *pchanf;
1172                 
1173                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1174                         if(arm->layer & pchan->bone->layer) {
1175                                 if(pchan->bone->flag & BONE_ACTIVE)
1176                                         break;
1177                         }
1178                 }
1179                 if(pchan) {
1180                         char name[32];
1181                         
1182                         BLI_strncpy(name, pchan->name, 32);
1183                         bone_flip_name(name, 1);        // 0 = do not strip off number extensions
1184                         
1185                         pchanf= get_pose_channel(ob->pose, name);
1186                         if(pchanf && pchanf!=pchan) {
1187                                 pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
1188                                 pchanf->bone->flag |= (BONE_SELECTED|BONE_ACTIVE);
1189                         
1190                                 /* in weightpaint we select the associated vertex group too */
1191                                 if(G.f & G_WEIGHTPAINT) {
1192                                         vertexgroup_select_by_name(OBACT, name);
1193                                         DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
1194                                 }
1195                                 
1196                                 select_actionchannel_by_name(ob->action, name, 1);
1197                                 
1198                                 allqueue(REDRAWVIEW3D, 0);
1199                                 allqueue(REDRAWACTION, 0);
1200                                 allqueue(REDRAWIPO, 0);         /* To force action/constraint ipo update */
1201                                 allqueue(REDRAWBUTSEDIT, 0);
1202                                 allqueue(REDRAWBUTSOBJECT, 0);
1203                                 allqueue(REDRAWOOPS, 0);
1204                         }                       
1205                 }
1206         }
1207 }
1208
1209 /* This function pops up the move-to-layer popup widgets when the user
1210  * presses either SHIFT-MKEY or MKEY in PoseMode OR EditMode (for Armatures)
1211  */
1212 void pose_movetolayer(void)
1213 {
1214         Object *ob= OBACT;
1215         bArmature *arm;
1216         short lay= 0;
1217         
1218         if (ob==NULL) return;
1219         arm= ob->data;
1220         
1221         if (G.qual & LR_SHIFTKEY) {
1222                 /* armature layers */
1223                 lay= arm->layer;
1224                 if ( movetolayer_short_buts(&lay, "Armature Layers")==0 ) return;
1225                 if (lay==0) return;
1226                 arm->layer= lay;
1227                 if(ob->pose)
1228                         ob->pose->proxy_layer= lay;
1229                 
1230                 allqueue(REDRAWVIEW3D, 0);
1231                 allqueue(REDRAWACTION, 0);
1232                 allqueue(REDRAWBUTSEDIT, 0);
1233         }
1234         else if (G.obedit) {
1235                 /* the check for editbone layer moving needs to occur before posemode one to work */
1236                 EditBone *ebo;
1237                 EditBone *flipBone;
1238                 
1239                 for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
1240                         if (arm->layer & ebo->layer) {
1241                                 if (ebo->flag & BONE_SELECTED)
1242                                         lay |= ebo->layer;
1243                         }
1244                 }
1245                 if (lay==0) return;
1246                 
1247                 if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
1248                 if (lay==0) return;
1249                 
1250                 for (ebo= G.edbo.first; ebo; ebo= ebo->next) {
1251                         if (arm->layer & ebo->layer) {
1252                                 if (ebo->flag & BONE_SELECTED) {
1253                                         ebo->layer= lay;
1254                                         if (arm->flag & ARM_MIRROR_EDIT) {
1255                                                 flipBone = armature_bone_get_mirrored(ebo);
1256                                                 if (flipBone)
1257                                                         flipBone->layer = lay;
1258                                         }
1259                                 }
1260                         }
1261                 }
1262                 
1263                 BIF_undo_push("Move Bone Layer");
1264                 allqueue(REDRAWVIEW3D, 0);
1265                 allqueue(REDRAWBUTSEDIT, 0);
1266         }
1267         else if (ob->flag & OB_POSEMODE) {
1268                 /* pose-channel layers */
1269                 bPoseChannel *pchan;
1270                 
1271                 if (pose_has_protected_selected(ob, 0))
1272                         return;
1273                 
1274                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1275                         if (arm->layer & pchan->bone->layer) {
1276                                 if (pchan->bone->flag & BONE_SELECTED)
1277                                         lay |= pchan->bone->layer;
1278                         }
1279                 }
1280                 if (lay==0) return;
1281                 
1282                 if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
1283                 if (lay==0) 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_SELECTED)
1288                                         pchan->bone->layer= lay;
1289                         }
1290                 }
1291                 
1292                 BIF_undo_push("Move Bone Layer");
1293                 allqueue(REDRAWVIEW3D, 0);
1294                 allqueue(REDRAWACTION, 0);
1295                 allqueue(REDRAWBUTSEDIT, 0);
1296         }
1297 }
1298
1299
1300 /* for use with pose_relax only */
1301 static int pose_relax_icu(struct IpoCurve *icu, float framef, float *val, float *frame_prev, float *frame_next)
1302 {
1303         if (!icu) {
1304                 return 0;
1305         } else {
1306                 BezTriple *bezt = icu->bezt;
1307                 
1308                 BezTriple *bezt_prev=NULL, *bezt_next=NULL;
1309                 float w1, w2, wtot;
1310                 int i;
1311                 
1312                 for (i=0; i < icu->totvert; i++, bezt++) {
1313                         if (bezt->vec[1][0] < framef - 0.5) {
1314                                 bezt_prev = bezt;
1315                         } else {
1316                                 break;
1317                         }
1318                 }
1319                 
1320                 if (bezt_prev==NULL) return 0;
1321                 
1322                 /* advance to the next, dont need to advance i */
1323                 bezt = bezt_prev+1;
1324                 
1325                 for (; i < icu->totvert; i++, bezt++) {
1326                         if (bezt->vec[1][0] > framef + 0.5) {
1327                                 bezt_next = bezt;
1328                                                 break;
1329                         }
1330                 }
1331                 
1332                 if (bezt_next==NULL) return 0;
1333         
1334                 if (val) {
1335                         w1 = framef - bezt_prev->vec[1][0];
1336                         w2 = bezt_next->vec[1][0] - framef;
1337                         wtot = w1 + w2;
1338                         w1=w1/wtot;
1339                         w2=w2/wtot;
1340 #if 0
1341                         val = (bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1);
1342 #else
1343                         /* apply the value with a hard coded 6th */
1344                         *val = (((bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1)) + (*val * 5.0f)) / 6.0f;
1345 #endif
1346                 }
1347                 
1348                 if (frame_prev) *frame_prev = bezt_prev->vec[1][0];
1349                 if (frame_next) *frame_next = bezt_next->vec[1][0];
1350                 
1351                 return 1;
1352         }
1353 }
1354
1355 void pose_relax()
1356 {
1357         Object *ob = OBACT;
1358         bPose *pose;
1359         bAction *act;
1360         bArmature *arm;
1361         
1362         IpoCurve *icu_w, *icu_x, *icu_y, *icu_z;
1363         
1364         bPoseChannel *pchan;
1365         bActionChannel *achan;
1366         float framef = F_CFRA;
1367         float frame_prev, frame_next;
1368         float quat_prev[4], quat_next[4], quat_interp[4], quat_orig[4];
1369         
1370         int do_scale = 0;
1371         int do_loc = 0;
1372         int do_quat = 0;
1373         int flag = 0;
1374         int do_x, do_y, do_z;
1375         
1376         if (!ob) return;
1377         
1378         pose = ob->pose;
1379         act = ob->action;
1380         arm = (bArmature *)ob->data;
1381         
1382         if (!pose || !act || !arm) return;
1383         
1384         for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
1385                 if (pchan->bone->layer & arm->layer) {
1386                         if (pchan->bone->flag & BONE_SELECTED) {
1387                                 /* do we have an ipo curve? */
1388                                 achan= get_action_channel(act, pchan->name);
1389                                 
1390                                 if (achan && achan->ipo) {
1391                                         /*calc_ipo(achan->ipo, ctime);*/
1392                                         
1393                                         do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_X), framef, &pchan->loc[0], NULL, NULL);
1394                                         do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Y), framef, &pchan->loc[1], NULL, NULL);
1395                                         do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Z), framef, &pchan->loc[2], NULL, NULL);
1396                                         do_loc += do_x + do_y + do_z;
1397                                         
1398                                         do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_X), framef, &pchan->size[0], NULL, NULL);
1399                                         do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Y), framef, &pchan->size[1], NULL, NULL);
1400                                         do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Z), framef, &pchan->size[2], NULL, NULL);
1401                                         do_scale += do_x + do_y + do_z;
1402                                                 
1403                                         if(     ((icu_w = find_ipocurve(achan->ipo, AC_QUAT_W))) &&
1404                                                 ((icu_x = find_ipocurve(achan->ipo, AC_QUAT_X))) &&
1405                                                 ((icu_y = find_ipocurve(achan->ipo, AC_QUAT_Y))) &&
1406                                                 ((icu_z = find_ipocurve(achan->ipo, AC_QUAT_Z))) )
1407                                         {
1408                                                 /* use the quatw keyframe as a basis for others */
1409                                                 if (pose_relax_icu(icu_w, framef, NULL, &frame_prev, &frame_next)) {
1410                                                         /* get 2 quats */
1411                                                         quat_prev[0] = eval_icu(icu_w, frame_prev);
1412                                                         quat_prev[1] = eval_icu(icu_x, frame_prev);
1413                                                         quat_prev[2] = eval_icu(icu_y, frame_prev);
1414                                                         quat_prev[3] = eval_icu(icu_z, frame_prev);
1415                                                         
1416                                                         quat_next[0] = eval_icu(icu_w, frame_next);
1417                                                         quat_next[1] = eval_icu(icu_x, frame_next);
1418                                                         quat_next[2] = eval_icu(icu_y, frame_next);
1419                                                         quat_next[3] = eval_icu(icu_z, frame_next);
1420                                                         
1421 #if 0
1422                                                         /* apply the setting, completely smooth */
1423                                                         QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
1424 #else
1425                                                         /* tricky interpolation */
1426                                                         QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
1427                                                         QUATCOPY(quat_orig, pchan->quat);
1428                                                         QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
1429                                                         /* done */
1430 #endif
1431                                                         do_quat++;
1432                                                 }
1433                                         }
1434                                         
1435                                         /* apply BONE_TRANSFORM tag so that autokeying will pick it up */
1436                                         pchan->bone->flag |= BONE_TRANSFORM;
1437                                 }
1438                         }
1439                 }
1440         }
1441         
1442         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
1443         
1444         /* do auto-keying */
1445         if (do_loc)             flag |= TFM_TRANSLATION;
1446         if (do_scale)   flag |= TFM_RESIZE;
1447         if (do_quat)    flag |= TFM_ROTATION;
1448         autokeyframe_pose_cb_func(ob, flag, 0);
1449          
1450         /* clear BONE_TRANSFORM flags */
1451         for (pchan=pose->chanbase.first; pchan; pchan= pchan->next)
1452                 pchan->bone->flag &= ~ BONE_TRANSFORM;
1453         
1454         /* do depsgraph flush */
1455         DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
1456         BIF_undo_push("Relax Pose");
1457 }