0771806a4a2ccdaa652f3689695ba102b84de4ec
[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_transform.h" /* for autokey TFM_TRANSLATION, etc */
68 #include "BIF_gl.h"
69
70 #include "RNA_access.h"
71 #include "RNA_define.h"
72
73 #include "WM_api.h"
74 #include "WM_types.h"
75
76 #include "ED_armature.h"
77 #include "ED_anim_api.h"
78 #include "ED_keyframing.h"
79 #include "ED_object.h"
80 #include "ED_mesh.h"
81 #include "ED_view3d.h"
82
83 #include "armature_intern.h"
84
85 /* ************* XXX *************** */
86 static int movetolayer_short_buts() {return 1;}
87 static int okee() {return 0;}
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 add_constraint() {}
94 static void autokeyframe_pose_cb_func() {}
95 /* ************* XXX *************** */
96
97 /* This function is used to indicate that a bone is selected and needs keyframes inserted */
98 void set_pose_keys (Object *ob)
99 {
100         bArmature *arm= ob->data;
101         bPoseChannel *chan;
102
103         if (ob->pose){
104                 for (chan=ob->pose->chanbase.first; chan; chan=chan->next){
105                         Bone *bone= chan->bone;
106                         if ((bone) && (bone->flag & BONE_SELECTED) && (arm->layer & bone->layer))
107                                 chan->flag |= POSE_KEY; 
108                         else
109                                 chan->flag &= ~POSE_KEY;
110                 }
111         }
112 }
113
114 /* This function is used to process the necessary updates for */
115 void ED_armature_enter_posemode(bContext *C, Base *base)
116 {
117         Object *ob= base->object;
118         
119         if (ob->id.lib){
120                 error ("Can't pose libdata");
121                 return;
122         }
123         
124         switch (ob->type){
125                 case OB_ARMATURE:
126                         
127                         ob->flag |= OB_POSEMODE;
128                         base->flag= ob->flag;
129                         
130                         WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_POSEMODE, NULL);
131                         
132                         break;
133                 default:
134                         return;
135         }
136         ED_view3d_exit_paint_modes(C);
137 }
138
139 void ED_armature_exit_posemode(bContext *C, Base *base)
140 {
141         if(base) {
142                 Object *ob= base->object;
143                 
144                 ob->flag &= ~OB_POSEMODE;
145                 base->flag= ob->flag;
146                 
147                 WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
148         }       
149 }
150
151 /* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */
152 /* only_selected==1 : the active bone is allowed to be protected */
153 static short pose_has_protected_selected(Object *ob, short only_selected, short warn)
154 {
155         /* check protection */
156         if (ob->proxy) {
157                 bPoseChannel *pchan;
158                 bArmature *arm= ob->data;
159                 
160                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
161                         if (pchan->bone && (pchan->bone->layer & arm->layer)) {
162                                 if (pchan->bone->layer & arm->layer_protected) {
163                                         if (only_selected && (pchan->bone->flag & BONE_ACTIVE));
164                                         else if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) 
165                                            break;
166                                 }
167                         }
168                 }
169                 if (pchan) {
170                         if (warn) error("Cannot change Proxy protected bones");
171                         return 1;
172                 }
173         }
174         return 0;
175 }
176
177 /* only for real IK, not for auto-IK */
178 int ED_pose_channel_in_IK_chain(Object *ob, bPoseChannel *pchan)
179 {
180         bConstraint *con;
181         Bone *bone;
182         
183         /* No need to check if constraint is active (has influence),
184          * since all constraints with CONSTRAINT_IK_AUTO are active */
185         for(con= pchan->constraints.first; con; con= con->next) {
186                 if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
187                         bKinematicConstraint *data= con->data;
188                         if((data->flag & CONSTRAINT_IK_AUTO)==0)
189                                 return 1;
190                 }
191         }
192         for(bone= pchan->bone->childbase.first; bone; bone= bone->next) {
193                 pchan= get_pose_channel(ob->pose, bone->name);
194                 if(pchan && ED_pose_channel_in_IK_chain(ob, pchan))
195                         return 1;
196         }
197         return 0;
198 }
199
200 /* ********************************************** */
201
202 /* For the object with pose/action: create path curves for selected bones 
203  * This recalculates the WHOLE path within the pchan->pathsf and pchan->pathef range
204  */
205 void pose_calculate_path(bContext *C, Scene *scene, Object *ob)
206 {
207         bArmature *arm;
208         bPoseChannel *pchan;
209         Base *base;
210         float *fp;
211         int cfra;
212         int sfra, efra;
213         
214         if (ob==NULL || ob->pose==NULL)
215                 return;
216         arm= ob->data;
217         
218         /* version patch for older files here (do_versions patch too complicated) */
219         if ((arm->pathsf == 0) || (arm->pathef == 0)) {
220                 arm->pathsf = SFRA;
221                 arm->pathef = EFRA;
222         }
223         if (arm->pathsize == 0) {
224                 arm->pathsize = 1;
225         }
226         
227         /* set frame values */
228         cfra= CFRA;
229         sfra = arm->pathsf;
230         efra = arm->pathef;
231         if (efra <= sfra) {
232                 error("Can't calculate paths when pathlen <= 0");
233                 return;
234         }
235         
236         waitcursor(1);
237         
238         /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
239         if ((ob->recalc & OB_RECALC)==0) {
240                 ob->recalc |= OB_RECALC;
241                 ED_anim_object_flush_update(C, ob);
242         }
243         else
244                 ED_anim_object_flush_update(C, ob);
245         
246         
247         /* malloc the path blocks */
248         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
249                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
250                         if (arm->layer & pchan->bone->layer) {
251                                 pchan->pathlen= efra-sfra+1;
252                                 pchan->pathsf= sfra;
253                                 pchan->pathef= efra+1;
254                                 if (pchan->path)
255                                         MEM_freeN(pchan->path);
256                                 pchan->path= MEM_callocN(3*pchan->pathlen*sizeof(float), "pchan path");
257                         }
258                 }
259         }
260         
261         for (CFRA=sfra; CFRA<=efra; CFRA++) {
262                 /* do all updates */
263                 for (base= FIRSTBASE; base; base= base->next) {
264                         if (base->object->recalc) {
265                                 int temp= base->object->recalc;
266                                 object_handle_update(scene, base->object);
267                                 base->object->recalc= temp;
268                         }
269                 }
270                 
271                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
272                         if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
273                                 if (arm->layer & pchan->bone->layer) {
274                                         if (pchan->path) {
275                                                 fp= pchan->path+3*(CFRA-sfra);
276                                                 
277                                                 if (arm->pathflag & ARM_PATH_HEADS) { 
278                                                         VECCOPY(fp, pchan->pose_head);
279                                                 }
280                                                 else {
281                                                         VECCOPY(fp, pchan->pose_tail);
282                                                 }
283                                                 
284                                                 Mat4MulVecfl(ob->obmat, fp);
285                                         }
286                                 }
287                         }
288                 }
289         }
290         
291         waitcursor(0);
292         
293         CFRA= cfra;
294 }
295
296 /* For the object with pose/action: update paths for those that have got them
297  * This should selectively update paths that exist...
298  */
299 void pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
300 {
301         bArmature *arm;
302         bPoseChannel *pchan;
303         Base *base;
304         float *fp;
305         int cfra;
306         int sfra, efra;
307         
308         if (ob==NULL || ob->pose==NULL)
309                 return;
310         arm= ob->data;
311         
312         /* set frame values */
313         cfra = CFRA;
314         sfra = efra = cfra; 
315         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
316                 if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
317                         if (pchan->path) {
318                                 /* if the pathsf and pathef aren't initialised, abort! */
319                                 if (ELEM(0, pchan->pathsf, pchan->pathef))      
320                                         return;
321                                 
322                                 /* try to increase area to do (only as much as needed) */
323                                 sfra= MIN2(sfra, pchan->pathsf);
324                                 efra= MAX2(efra, pchan->pathef);
325                         }
326                 }
327         }
328         if (efra <= sfra) return;
329         
330         waitcursor(1);
331         
332         /* hack: for unsaved files, set OB_RECALC so that paths can get calculated */
333         if ((ob->recalc & OB_RECALC)==0) {
334                 ob->recalc |= OB_RECALC;
335                 ED_anim_object_flush_update(C, ob);
336         }
337         else
338                 ED_anim_object_flush_update(C, ob);
339         
340         for (CFRA=sfra; CFRA<=efra; CFRA++) {
341                 /* do all updates */
342                 for (base= FIRSTBASE; base; base= base->next) {
343                         if (base->object->recalc) {
344                                 int temp= base->object->recalc;
345                                 object_handle_update(scene, base->object);
346                                 base->object->recalc= temp;
347                         }
348                 }
349                 
350                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
351                         if ((pchan->bone) && (arm->layer & pchan->bone->layer)) {
352                                 if (pchan->path) {
353                                         /* only update if:
354                                          *      - in range of this pchan's existing path
355                                          *      - ... insert evil filtering/optimising conditions here...
356                                          */
357                                         if (IN_RANGE(CFRA, pchan->pathsf, pchan->pathef)) {
358                                                 fp= pchan->path+3*(CFRA-sfra);
359                                                 
360                                                 if (arm->pathflag & ARM_PATH_HEADS) { 
361                                                         VECCOPY(fp, pchan->pose_head);
362                                                 }
363                                                 else {
364                                                         VECCOPY(fp, pchan->pose_tail);
365                                                 }
366                                                 
367                                                 Mat4MulVecfl(ob->obmat, fp);
368                                         }
369                                 }
370                         }
371                 }
372         }
373         
374         waitcursor(0);
375         
376         CFRA= cfra;
377         ob->pose->flag &= ~POSE_RECALCPATHS;
378 }
379
380 /* for the object with pose/action: clear path curves for selected bones only */
381 void pose_clear_paths(Object *ob)
382 {
383         bPoseChannel *pchan;
384         
385         if (ob==NULL || ob->pose==NULL)
386                 return;
387         
388         /* free the path blocks */
389         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
390                 if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) {
391                         if (pchan->path) {
392                                 MEM_freeN(pchan->path);
393                                 pchan->path= NULL;
394                         }
395                 }
396         }
397         
398 }
399
400
401
402 void pose_select_constraint_target(Scene *scene)
403 {
404         Object *obedit= scene->obedit; // XXX context
405         Object *ob= OBACT;
406         bArmature *arm= ob->data;
407         bPoseChannel *pchan;
408         bConstraint *con;
409         
410         /* paranoia checks */
411         if (!ob && !ob->pose) return;
412         if (ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
413         
414         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
415                 if (arm->layer & pchan->bone->layer) {
416                         if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
417                                 for (con= pchan->constraints.first; con; con= con->next) {
418                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
419                                         ListBase targets = {NULL, NULL};
420                                         bConstraintTarget *ct;
421                                         
422                                         if (cti && cti->get_constraint_targets) {
423                                                 cti->get_constraint_targets(con, &targets);
424                                                 
425                                                 for (ct= targets.first; ct; ct= ct->next) {
426                                                         if ((ct->tar == ob) && (ct->subtarget[0])) {
427                                                                 bPoseChannel *pchanc= get_pose_channel(ob->pose, ct->subtarget);
428                                                                 if(pchanc)
429                                                                         pchanc->bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
430                                                         }
431                                                 }
432                                                 
433                                                 if (cti->flush_constraint_targets)
434                                                         cti->flush_constraint_targets(con, &targets, 1);
435                                         }
436                                 }
437                         }
438                 }
439         }
440         
441         BIF_undo_push("Select constraint target");
442
443 }
444
445 void pose_select_hierarchy(Scene *scene, short direction, short add_to_sel)
446 {
447         Object *obedit= scene->obedit; // XXX context
448         Object *ob= OBACT;
449         bArmature *arm= ob->data;
450         bPoseChannel *pchan;
451         Bone *curbone, *pabone, *chbone;
452         
453         /* paranoia checks */
454         if (!ob && !ob->pose) return;
455         if (ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
456         
457         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
458                 curbone= pchan->bone;
459                 
460                 if (arm->layer & curbone->layer) {
461                         if (curbone->flag & (BONE_ACTIVE)) {
462                                 if (direction == BONE_SELECT_PARENT) {
463                                 
464                                         if (pchan->parent == NULL) continue;
465                                         else pabone= pchan->parent->bone;
466                                         
467                                         if ((arm->layer & pabone->layer) && !(pabone->flag & BONE_HIDDEN_P)) {
468                                                 
469                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
470                                                 curbone->flag &= ~BONE_ACTIVE;
471                                                 pabone->flag |= (BONE_ACTIVE|BONE_SELECTED);
472                                                 
473                                                 // XXX notifiers need to be sent to other editors to update
474                                                 break;
475                                         }
476                                 } else { // BONE_SELECT_CHILD
477                                 
478                                         if (pchan->child == NULL) continue;
479                                         else chbone = pchan->child->bone;
480                                         
481                                         if ((arm->layer & chbone->layer) && !(chbone->flag & BONE_HIDDEN_P)) {
482                                         
483                                                 if (!add_to_sel) curbone->flag &= ~BONE_SELECTED;
484                                                 curbone->flag &= ~BONE_ACTIVE;
485                                                 chbone->flag |= (BONE_ACTIVE|BONE_SELECTED);
486                                                 
487                                                 // XXX notifiers need to be sent to other editors to update
488                                                 break;
489                                         }
490                                 }
491                         }
492                 }
493         }
494         
495         if (direction==BONE_SELECT_PARENT)
496                 BIF_undo_push("Select pose bone parent");
497         if (direction==BONE_SELECT_CHILD)
498                 BIF_undo_push("Select pose bone child");
499 }
500
501
502 void pose_add_IK(Scene *scene)
503 {
504         Object *obedit= scene->obedit; // XXX context
505         Object *ob= OBACT;
506         
507         /* paranoia checks */
508         if(!ob && !ob->pose) return;
509         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
510         
511         add_constraint(1);      /* 1 means only IK */
512 }
513
514 /* context: all selected channels */
515 void pose_clear_IK(Scene *scene)
516 {
517         Object *obedit= scene->obedit; // XXX context
518         Object *ob= OBACT;
519         bArmature *arm= ob->data;
520         bPoseChannel *pchan;
521         bConstraint *con;
522         bConstraint *next;
523         
524         /* paranoia checks */
525         if(!ob && !ob->pose) return;
526         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
527         
528         if(pose_has_protected_selected(ob, 0, 1))
529                 return;
530         
531         if(okee("Remove IK constraint(s)")==0) return;
532
533         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
534                 if(arm->layer & pchan->bone->layer) {
535                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
536                                 
537                                 for(con= pchan->constraints.first; con; con= next) {
538                                         next= con->next;
539                                         if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
540                                                 BLI_remlink(&pchan->constraints, con);
541                                                 free_constraint_data(con);
542                                                 MEM_freeN(con);
543                                         }
544                                 }
545                                 pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
546                         }
547                 }
548         }
549         
550         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);     // and all its relations
551         
552         BIF_undo_push("Remove IK constraint(s)");
553 }
554
555 void pose_clear_constraints(Scene *scene)
556 {
557         Object *obedit= scene->obedit; // XXX context
558         Object *ob= OBACT;
559         bArmature *arm= ob->data;
560         bPoseChannel *pchan;
561         
562         /* paranoia checks */
563         if(!ob && !ob->pose) return;
564         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
565         
566         if(pose_has_protected_selected(ob, 0, 1))
567                 return;
568         
569         if(okee("Remove Constraints")==0) return;
570         
571         /* find active */
572         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
573                 if(arm->layer & pchan->bone->layer) {
574                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
575                                 free_constraints(&pchan->constraints);
576                                 pchan->constflag= 0;
577                         }
578                 }
579         }
580         
581         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);     // and all its relations
582         
583         BIF_undo_push("Remove Constraint(s)");
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) {
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
1216 void pose_select_grouped (Scene *scene, short nr)
1217 {
1218         short changed = 0;
1219         
1220         if (nr == 1)            changed= pose_select_same_group(OBACT);
1221         else if (nr == 2)       changed= pose_select_same_layer(OBACT);
1222         
1223         if (changed) {
1224                 countall();
1225                 BIF_undo_push("Select Grouped");
1226         }
1227 }
1228
1229 /* Shift-G in 3D-View while in PoseMode */
1230 void pose_select_grouped_menu (Scene *scene)
1231 {
1232         short nr;
1233         
1234         /* here we go */
1235         nr= pupmenu("Select Grouped%t|In Same Group%x1|In Same Layer%x2");
1236         pose_select_grouped(scene, nr);
1237 }
1238
1239 /* ********************************************** */
1240
1241 /* context active object */
1242 void pose_flip_names(Scene *scene)
1243 {
1244         Object *obedit= scene->obedit; // XXX context
1245         Object *ob= OBACT;
1246         bArmature *arm= ob->data;
1247         bPoseChannel *pchan;
1248         char newname[32];
1249         
1250         /* paranoia checks */
1251         if(!ob && !ob->pose) return;
1252         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
1253         
1254         if(pose_has_protected_selected(ob, 0, 1))
1255                 return;
1256         
1257         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1258                 if(arm->layer & pchan->bone->layer) {
1259                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1260                                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1261                                 bone_flip_name(newname, 1);     // 1 = do strip off number extensions
1262                                 armature_bone_rename(ob, pchan->name, newname);
1263                         }
1264                 }
1265         }
1266         
1267         BIF_undo_push("Flip names");
1268 }
1269
1270 /* context active object */
1271 void pose_autoside_names(Scene *scene, short axis)
1272 {
1273         Object *obedit= scene->obedit; // XXX context
1274         Object *ob= OBACT;
1275         bArmature *arm= ob->data;
1276         bPoseChannel *pchan;
1277         char newname[32];
1278         
1279         /* paranoia checks */
1280         if (ELEM(NULL, ob, ob->pose)) return;
1281         if (ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
1282         
1283         if (pose_has_protected_selected(ob, 0, 1))
1284                 return;
1285         
1286         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1287                 if(arm->layer & pchan->bone->layer) {
1288                         if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) {
1289                                 BLI_strncpy(newname, pchan->name, sizeof(newname));
1290                                 bone_autoside_name(newname, 1, axis, pchan->bone->head[axis], pchan->bone->tail[axis]);
1291                                 armature_bone_rename(ob, pchan->name, newname);
1292                         }
1293                 }
1294         }
1295         
1296         BIF_undo_push("Flip names");
1297 }
1298
1299 /* context active object, or weightpainted object with armature in posemode */
1300 void pose_activate_flipped_bone(Scene *scene)
1301 {
1302         Object *ob= OBACT;
1303         bArmature *arm= ob->data;
1304         
1305         if(ob==NULL) return;
1306
1307         if(G.f & G_WEIGHTPAINT) {
1308                 ob= modifiers_isDeformedByArmature(ob);
1309         }
1310         if(ob && (ob->flag & OB_POSEMODE)) {
1311                 bPoseChannel *pchan, *pchanf;
1312                 
1313                 for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1314                         if(arm->layer & pchan->bone->layer) {
1315                                 if(pchan->bone->flag & BONE_ACTIVE)
1316                                         break;
1317                         }
1318                 }
1319                 if(pchan) {
1320                         char name[32];
1321                         
1322                         BLI_strncpy(name, pchan->name, 32);
1323                         bone_flip_name(name, 1);        // 0 = do not strip off number extensions
1324                         
1325                         pchanf= get_pose_channel(ob->pose, name);
1326                         if(pchanf && pchanf!=pchan) {
1327                                 pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE);
1328                                 pchanf->bone->flag |= (BONE_SELECTED|BONE_ACTIVE);
1329                         
1330                                 /* in weightpaint we select the associated vertex group too */
1331                                 if(G.f & G_WEIGHTPAINT) {
1332                                         vertexgroup_select_by_name(OBACT, name);
1333                                         DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA);
1334                                 }
1335                                 
1336                                 // XXX notifiers need to be sent to other editors to update
1337                                 
1338                         }                       
1339                 }
1340         }
1341 }
1342
1343 /* This function pops up the move-to-layer popup widgets when the user
1344  * presses either SHIFT-MKEY or MKEY in PoseMode OR EditMode (for Armatures)
1345  */
1346 void pose_movetolayer(Scene *scene)
1347 {
1348         Object *obedit= scene->obedit; // XXX context
1349         Object *ob= OBACT;
1350         bArmature *arm;
1351         short lay= 0;
1352         short shift= 0; // XXX
1353         
1354         if (ob==NULL) return;
1355         arm= ob->data;
1356         
1357         if (shift) {
1358                 /* armature layers */
1359                 lay= arm->layer;
1360                 if ( movetolayer_short_buts(&lay, "Armature Layers")==0 ) return;
1361                 if (lay==0) return;
1362                 arm->layer= lay;
1363                 if(ob->pose)
1364                         ob->pose->proxy_layer= lay;
1365                 
1366         }
1367         else if (obedit) {
1368                 /* the check for editbone layer moving needs to occur before posemode one to work */
1369                 EditBone *ebo;
1370                 EditBone *flipBone;
1371                 
1372                 for (ebo= arm->edbo->first; ebo; ebo= ebo->next) {
1373                         if (arm->layer & ebo->layer) {
1374                                 if (ebo->flag & BONE_SELECTED)
1375                                         lay |= ebo->layer;
1376                         }
1377                 }
1378                 if (lay==0) return;
1379                 
1380                 if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
1381                 if (lay==0) return;
1382                 
1383                 for (ebo= arm->edbo->first; ebo; ebo= ebo->next) {
1384                         if (arm->layer & ebo->layer) {
1385                                 if (ebo->flag & BONE_SELECTED) {
1386                                         ebo->layer= lay;
1387                                         if (arm->flag & ARM_MIRROR_EDIT) {
1388                                                 flipBone = armature_bone_get_mirrored(arm->edbo, ebo);
1389                                                 if (flipBone)
1390                                                         flipBone->layer = lay;
1391                                         }
1392                                 }
1393                         }
1394                 }
1395                 
1396                 BIF_undo_push("Move Bone Layer");
1397         }
1398         else if (ob->flag & OB_POSEMODE) {
1399                 /* pose-channel layers */
1400                 bPoseChannel *pchan;
1401                 
1402                 if (pose_has_protected_selected(ob, 0, 1))
1403                         return;
1404                 
1405                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1406                         if (arm->layer & pchan->bone->layer) {
1407                                 if (pchan->bone->flag & BONE_SELECTED)
1408                                         lay |= pchan->bone->layer;
1409                         }
1410                 }
1411                 if (lay==0) return;
1412                 
1413                 if ( movetolayer_short_buts(&lay, "Bone Layers")==0 ) return;
1414                 if (lay==0) return;
1415                 
1416                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1417                         if (arm->layer & pchan->bone->layer) {
1418                                 if (pchan->bone->flag & BONE_SELECTED)
1419                                         pchan->bone->layer= lay;
1420                         }
1421                 }
1422                 
1423                 BIF_undo_push("Move Bone Layer");
1424         }
1425 }
1426
1427 #if 0
1428 // XXX old sys
1429 /* for use with pose_relax only */
1430 static int pose_relax_icu(struct IpoCurve *icu, float framef, float *val, float *frame_prev, float *frame_next)
1431 {
1432         if (!icu) {
1433                 return 0;
1434         } 
1435         else {
1436                 BezTriple *bezt = icu->bezt;
1437                 
1438                 BezTriple *bezt_prev=NULL, *bezt_next=NULL;
1439                 float w1, w2, wtot;
1440                 int i;
1441                 
1442                 for (i=0; i < icu->totvert; i++, bezt++) {
1443                         if (bezt->vec[1][0] < framef - 0.5) {
1444                                 bezt_prev = bezt;
1445                         } else {
1446                                 break;
1447                         }
1448                 }
1449                 
1450                 if (bezt_prev==NULL) return 0;
1451                 
1452                 /* advance to the next, dont need to advance i */
1453                 bezt = bezt_prev+1;
1454                 
1455                 for (; i < icu->totvert; i++, bezt++) {
1456                         if (bezt->vec[1][0] > framef + 0.5) {
1457                                 bezt_next = bezt;
1458                                                 break;
1459                         }
1460                 }
1461                 
1462                 if (bezt_next==NULL) return 0;
1463         
1464                 if (val) {
1465                         w1 = framef - bezt_prev->vec[1][0];
1466                         w2 = bezt_next->vec[1][0] - framef;
1467                         wtot = w1 + w2;
1468                         w1=w1/wtot;
1469                         w2=w2/wtot;
1470 #if 0
1471                         val = (bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1);
1472 #else
1473                         /* apply the value with a hard coded 6th */
1474                         *val = (((bezt_prev->vec[1][1] * w2) + (bezt_next->vec[1][1] * w1)) + (*val * 5.0f)) / 6.0f;
1475 #endif
1476                 }
1477                 
1478                 if (frame_prev) *frame_prev = bezt_prev->vec[1][0];
1479                 if (frame_next) *frame_next = bezt_next->vec[1][0];
1480                 
1481                 return 1;
1482         }
1483 }
1484 #endif
1485
1486 void pose_relax(Scene *scene)
1487 {
1488         Object *ob = OBACT;
1489         bPose *pose;
1490         bAction *act;
1491         bArmature *arm;
1492         
1493 //      IpoCurve *icu_w, *icu_x, *icu_y, *icu_z;
1494         
1495         bPoseChannel *pchan;
1496 //      bActionChannel *achan;
1497 //      float framef = F_CFRA;
1498 //      float frame_prev, frame_next;
1499 //      float quat_prev[4], quat_next[4], quat_interp[4], quat_orig[4];
1500         
1501         int do_scale = 0;
1502         int do_loc = 0;
1503         int do_quat = 0;
1504         int flag = 0;
1505 //      int do_x, do_y, do_z;
1506         
1507         if (!ob) return;
1508         
1509         pose = ob->pose;
1510         act = ob->action;
1511         arm = (bArmature *)ob->data;
1512         
1513         if (!pose || !act || !arm) return;
1514         
1515         for (pchan=pose->chanbase.first; pchan; pchan= pchan->next) {
1516                 
1517                 pchan->bone->flag &= ~BONE_TRANSFORM;
1518                 
1519                 if (pchan->bone->layer & arm->layer) {
1520                         if (pchan->bone->flag & BONE_SELECTED) {
1521                                 /* do we have an ipo curve? */
1522 #if 0 // XXX old animation system
1523                                 achan= get_action_channel(act, pchan->name);
1524                                 
1525                                 if (achan && achan->ipo) {
1526                                         /*calc_ipo(achan->ipo, ctime);*/
1527                                         
1528                                         do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_X), framef, &pchan->loc[0], NULL, NULL);
1529                                         do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Y), framef, &pchan->loc[1], NULL, NULL);
1530                                         do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_LOC_Z), framef, &pchan->loc[2], NULL, NULL);
1531                                         do_loc += do_x + do_y + do_z;
1532                                         
1533                                         do_x = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_X), framef, &pchan->size[0], NULL, NULL);
1534                                         do_y = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Y), framef, &pchan->size[1], NULL, NULL);
1535                                         do_z = pose_relax_icu(find_ipocurve(achan->ipo, AC_SIZE_Z), framef, &pchan->size[2], NULL, NULL);
1536                                         do_scale += do_x + do_y + do_z;
1537                                                 
1538                                         if(     ((icu_w = find_ipocurve(achan->ipo, AC_QUAT_W))) &&
1539                                                 ((icu_x = find_ipocurve(achan->ipo, AC_QUAT_X))) &&
1540                                                 ((icu_y = find_ipocurve(achan->ipo, AC_QUAT_Y))) &&
1541                                                 ((icu_z = find_ipocurve(achan->ipo, AC_QUAT_Z))) )
1542                                         {
1543                                                 /* use the quatw keyframe as a basis for others */
1544                                                 if (pose_relax_icu(icu_w, framef, NULL, &frame_prev, &frame_next)) {
1545                                                         /* get 2 quats */
1546                                                         quat_prev[0] = eval_icu(icu_w, frame_prev);
1547                                                         quat_prev[1] = eval_icu(icu_x, frame_prev);
1548                                                         quat_prev[2] = eval_icu(icu_y, frame_prev);
1549                                                         quat_prev[3] = eval_icu(icu_z, frame_prev);
1550                                                         
1551                                                         quat_next[0] = eval_icu(icu_w, frame_next);
1552                                                         quat_next[1] = eval_icu(icu_x, frame_next);
1553                                                         quat_next[2] = eval_icu(icu_y, frame_next);
1554                                                         quat_next[3] = eval_icu(icu_z, frame_next);
1555                                                         
1556 #if 0
1557                                                         /* apply the setting, completely smooth */
1558                                                         QuatInterpol(pchan->quat, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
1559 #else
1560                                                         /* tricky interpolation */
1561                                                         QuatInterpol(quat_interp, quat_prev, quat_next, (framef-frame_prev) / (frame_next-frame_prev) );
1562                                                         QUATCOPY(quat_orig, pchan->quat);
1563                                                         QuatInterpol(pchan->quat, quat_orig, quat_interp, 1.0f/6.0f);
1564                                                         /* done */
1565 #endif
1566                                                         do_quat++;
1567                                                 }
1568                                         }
1569                                         
1570                                         /* apply BONE_TRANSFORM tag so that autokeying will pick it up */
1571                                         pchan->bone->flag |= BONE_TRANSFORM;
1572                                 }
1573                                 
1574 #endif // XXX old animation system
1575                         }
1576                 }
1577         }
1578         
1579         ob->pose->flag |= (POSE_LOCKED|POSE_DO_UNLOCK);
1580         
1581         /* do auto-keying */
1582         if (do_loc)             flag |= TFM_TRANSLATION;
1583         if (do_scale)   flag |= TFM_RESIZE;
1584         if (do_quat)    flag |= TFM_ROTATION;
1585         autokeyframe_pose_cb_func(ob, flag, 0);
1586          
1587         /* clear BONE_TRANSFORM flags */
1588         for (pchan=pose->chanbase.first; pchan; pchan= pchan->next)
1589                 pchan->bone->flag &= ~ BONE_TRANSFORM;
1590         
1591         /* do depsgraph flush */
1592         DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1593         BIF_undo_push("Relax Pose");
1594 }
1595
1596 /* for use in insertkey, ensure rotation goes other way around */
1597 void pose_flipquats(Scene *scene)
1598 {
1599         Object *ob = OBACT;
1600         bArmature *arm= ob->data;
1601         bPoseChannel *pchan;
1602         
1603         if(ob->pose==NULL)
1604                 return;
1605         
1606         /* find sel bones */
1607         for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
1608                 if(pchan->bone && (pchan->bone->flag & BONE_SELECTED) && (pchan->bone->layer & arm->layer)) {
1609                         /* quaternions have 720 degree range */
1610                         pchan->quat[0]= -pchan->quat[0];
1611                         pchan->quat[1]= -pchan->quat[1];
1612                         pchan->quat[2]= -pchan->quat[2];
1613                         pchan->quat[3]= -pchan->quat[3];
1614                 }
1615         }
1616         
1617         /* do autokey */
1618         autokeyframe_pose_cb_func(ob, TFM_ROTATION, 0);
1619 }
1620
1621 /* context: active channel */
1622 void pose_special_editmenu(Scene *scene)
1623 {
1624 #if 0
1625         Object *obedit= scene->obedit; // XXX context
1626         Object *ob= OBACT;
1627         short nr;
1628         
1629         /* paranoia checks */
1630         if(!ob && !ob->pose) return;
1631         if(ob==obedit || (ob->flag & OB_POSEMODE)==0) return;
1632         
1633         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");
1634         if(nr==1) {
1635                 pose_select_constraint_target(scene);
1636         }
1637         else if(nr==2) {
1638                 pose_flip_names();
1639         }
1640         else if(nr==3) {
1641                 pose_calculate_path(C, ob);
1642         }
1643         else if(nr==4) {
1644                 pose_clear_paths(ob);
1645         }
1646         else if(nr==5) {
1647                 rest_pose(ob->pose);
1648                 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
1649                 BIF_undo_push("Clear User Transform Pose");
1650         }
1651         else if(nr==6) {
1652                 pose_relax();
1653         }
1654         else if(ELEM3(nr, 7, 8, 9)) {
1655                 pose_autoside_names(nr-7);
1656         }
1657 #endif
1658 }
1659