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