Added x-ray bones support (sgefant ended up
[blender.git] / source / blender / src / editarmature.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  * editarmature.c: Interface for creating and posing armature objects
32  */
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <math.h>
37
38 #ifdef HAVE_CONFIG_H
39 #include <config.h>
40 #endif
41
42 #ifdef WIN32
43 #include "BLI_winstuff.h"
44 #endif
45
46 #include "MEM_guardedalloc.h"
47
48 #include "BMF_Api.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_arithb.h"
52 #include "BLI_editVert.h"
53
54 #include "DNA_action_types.h"
55 #include "DNA_armature_types.h"
56 #include "DNA_object_types.h"
57 #include "DNA_scene_types.h"
58 #include "DNA_screen_types.h"
59 #include "DNA_space_types.h"
60 #include "DNA_view3d_types.h"
61
62 #include "BKE_utildefines.h"
63 #include "BKE_action.h"
64 #include "BKE_armature.h"
65 #include "BKE_constraint.h"
66 #include "BKE_global.h"
67 #include "BKE_object.h"
68
69 #include "BIF_gl.h"
70 #include "BIF_graphics.h"
71 #include "BIF_interface.h"
72 #include "BIF_resources.h"
73 #include "BIF_screen.h"
74 #include "BIF_space.h"
75 #include "BIF_toolbox.h"
76 #include "BIF_editarmature.h"
77 #include "BIF_poseobject.h"
78 #include "BIF_mywindow.h"
79
80 #include "BDR_editobject.h"
81 #include "BDR_drawobject.h"
82
83 #include "BSE_edit.h"
84 #include "BSE_view.h"
85 #include "BSE_trans_types.h"
86 #include "BSE_editaction.h"
87
88 #include "mydevice.h"
89 #include "interface.h"
90 #include "blendef.h"
91 #include "nla.h"
92
93 /*  >>>>> FIXME: ARG!  Colours should be defined in a header somewhere! */
94 /*      Note, these came from drawobject.c  They really should be in a nice header file somewhere */
95 #define B_YELLOW        0x77FFFF
96 #define B_PURPLE        0xFF70FF
97
98 #define B_CYAN          0xFFFF00
99 #define B_AQUA          0xFFBB55 /* 0xFF8833*/
100
101 extern  int tottrans;                                   /* Originally defined in editobject.c */
102 extern  struct TransOb *transmain;                              /* Originally defined in editobject.c */
103 extern  float centre[3], centroid[3];   /* Originally defined in editobject.c */
104
105 /*      Macros  */
106 #define TEST_EDITARMATURE {if(G.obedit==0) return; if( (G.vd->lay & G.obedit->lay)==0 ) return;}
107
108 /* Local Function Prototypes */
109 static void editbones_to_armature (ListBase *bones, Object *ob);
110 static int editbone_to_parnr (EditBone *bone);
111
112 static void validate_editbonebutton(EditBone *bone);
113 static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist);
114 static int      select_bonechildren_by_name (struct Bone *bone, char *name, int select);
115 static void build_bonestring (char *string, struct EditBone *bone);
116 static void draw_boneverti (float x, float y, float z, float size, int flag);
117 static void draw_bone (int armflag, int boneflag, unsigned int id, char *name, float length);
118 static void draw_bonechildren (struct Bone *bone, int flag, unsigned int *index);
119 static void add_bone_input (struct Object *ob);
120 static void make_boneList(struct ListBase* list, struct ListBase *bones, struct EditBone *parent);
121 static void make_bone_menu_children (struct Bone *bone, char *str, int *index);
122 static void delete_bone(struct EditBone* exBone);
123 static void clear_armature_children (struct Bone *bone, struct bPose *pose, char mode);
124 static void parnr_to_editbone(EditBone *bone);
125
126 static int      count_bones (struct bArmature *arm, int flagmask, int allbones);
127
128 static int      count_bonechildren (struct Bone *bone, int incount, int flagmask, int allbones);
129 static int      add_trans_bonechildren (struct Object* ob, struct Bone* bone, struct TransOb* buffer, int index, char mode);
130 static void deselect_bonechildren (struct Bone *bone, int mode);
131 static void selectconnected_posebonechildren (struct Bone *bone);
132
133 static int      editbone_name_exists (char* name);
134 static void unique_editbone_name (char* name);
135 static void *get_nearest_bone (int findunsel);
136 static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask);
137
138 static void attach_bone_to_parent(EditBone *bone);
139 static Bone *get_first_selected_bonechildren (Bone *bone);
140
141
142 /* Functions */
143
144
145
146 void apply_rot_armature (Object *ob, float mat[3][3]){
147         ListBase        list;
148         EditBone *ebone;
149         bArmature *arm;
150
151         arm = get_armature(ob);
152
153         if (!arm)
154                 return;
155
156         /* Put the armature into editmode */
157         list.first= list.last = NULL;
158         make_boneList(&list, &arm->bonebase, NULL);
159
160         /* Do the rotations */
161         for (ebone = list.first; ebone; ebone=ebone->next){
162         
163                 {
164
165                         /* Fixme: This is essentially duplicated from join_armature */
166
167                         float premat[4][4];
168                         float postmat[4][4];
169                         float difmat[4][4];
170                         float imat[4][4];
171                         float temp[4][4];
172                         float delta[3];
173                         float rmat[4][4];
174                         
175                         Mat4CpyMat3 (rmat, mat);
176                         /* Get the premat */
177                         VecSubf (delta, ebone->tail, ebone->head);
178                         make_boneMatrixvr(temp, delta, ebone->roll);
179                         Mat4MulMat4 (premat, temp, rmat);
180                         
181                         Mat4MulVecfl(rmat, ebone->head);
182                         Mat4MulVecfl(rmat, ebone->tail);
183                         
184                         /* Get the postmat */
185                         VecSubf (delta, ebone->tail, ebone->head);
186                         make_boneMatrixvr(postmat, delta, ebone->roll);
187                         
188                         /* Find the roll */
189                         Mat4Invert (imat, premat);
190                         Mat4MulMat4 (difmat, postmat, imat);
191                         
192 #if 0
193                         printmatrix4 ("Difmat", difmat);
194 #endif
195                         ebone->roll -=atan(difmat[2][0]/difmat[2][2]);
196                         
197                         if (difmat[0][0]<0)
198                                 ebone->roll +=M_PI;
199                         
200                 }
201
202                 
203         }
204         
205         /* Turn the list into an armature */
206         editbones_to_armature(&list, ob);
207         
208         /* Free the editbones */
209         if (list.first){
210                 BLI_freelistN (&list);
211         }
212
213 }
214
215
216
217 static Bone *get_first_selected_bonechildren (Bone *bone)
218 {
219         Bone *curbone, *result;
220
221         if (bone->flag & BONE_SELECTED)
222                 return bone;
223
224         for (curbone = bone->childbase.first; curbone; curbone=curbone->next){
225                 result = get_first_selected_bonechildren(curbone);
226                 if (result)
227                         return result;
228         };
229
230         return NULL;
231 }
232
233 Bone *get_first_selected_bone (void)
234 {
235         Bone *curbone, *result;
236         bArmature *arm;
237
238         arm = get_armature(OBACT);
239         if (!arm)
240                 return NULL;
241
242         for (curbone = arm->bonebase.first; curbone; curbone=curbone->next){
243                 result = get_first_selected_bonechildren(curbone);
244                 if (result)
245                         return result;
246         }
247
248         return NULL;
249 }
250
251 void clever_numbuts_posearmature (void)
252 {
253         bArmature *arm;
254         Bone *bone;
255         bPoseChannel *chan;
256
257         arm = get_armature(OBACT);
258         if (!arm)
259                 return;
260
261         bone = get_first_selected_bone();
262
263         if (!bone)
264                 return;
265
266         add_numbut(0, NUM|FLO, "Loc X:", -G.vd->far, G.vd->far, bone->loc, 0);
267         add_numbut(1, NUM|FLO, "Loc Y:", -G.vd->far, G.vd->far, bone->loc+1, 0);
268         add_numbut(2, NUM|FLO, "Loc Z:", -G.vd->far, G.vd->far, bone->loc+2, 0);
269
270         add_numbut(3, NUM|FLO, "Quat X:", -G.vd->far, G.vd->far, bone->quat, 0);
271         add_numbut(4, NUM|FLO, "Quat Y:", -G.vd->far, G.vd->far, bone->quat+1, 0);
272         add_numbut(5, NUM|FLO, "Quat Z:", -G.vd->far, G.vd->far, bone->quat+2, 0);
273         add_numbut(6, NUM|FLO, "Quat W:", -G.vd->far, G.vd->far, bone->quat+3, 0);
274
275         add_numbut(7, NUM|FLO, "Size X:", -G.vd->far, G.vd->far, bone->size, 0);
276         add_numbut(8, NUM|FLO, "Size Y:", -G.vd->far, G.vd->far, bone->size+1, 0);
277         add_numbut(9, NUM|FLO, "Size Z:", -G.vd->far, G.vd->far, bone->size+2, 0);
278
279         do_clever_numbuts("Active Bone", 10, REDRAW);
280
281         /* This is similar to code in special_trans_update */
282         
283         if (!G.obpose->pose) G.obpose->pose= MEM_callocN(sizeof(bPose), "pose");
284         chan = MEM_callocN (sizeof (bPoseChannel), "transPoseChannel");
285
286         chan->flag |= POSE_LOC|POSE_ROT|POSE_SIZE;
287         memcpy (chan->loc, bone->loc, sizeof (chan->loc));
288         memcpy (chan->quat, bone->quat, sizeof (chan->quat));
289         memcpy (chan->size, bone->size, sizeof (chan->size));
290         strcpy (chan->name, bone->name);
291         
292         set_pose_channel (G.obpose->pose, chan);
293         
294 }
295
296 void clever_numbuts_armature (void)
297 {
298         EditBone *ebone, *child;
299         
300         ebone= G.edbo.first;
301
302         for (ebone = G.edbo.first; ebone; ebone=ebone->next){
303                 if (ebone->flag & BONE_SELECTED)
304                         break;
305         }
306
307         if (!ebone)
308                 return;
309
310         add_numbut(0, NUM|FLO, "Root X:", -G.vd->far, G.vd->far, ebone->head, 0);
311         add_numbut(1, NUM|FLO, "Root Y:", -G.vd->far, G.vd->far, ebone->head+1, 0);
312         add_numbut(2, NUM|FLO, "Root Z:", -G.vd->far, G.vd->far, ebone->head+2, 0);
313
314         add_numbut(3, NUM|FLO, "Tip X:", -G.vd->far, G.vd->far, ebone->tail, 0);
315         add_numbut(4, NUM|FLO, "Tip Y:", -G.vd->far, G.vd->far, ebone->tail+1, 0);
316         add_numbut(5, NUM|FLO, "Tip Z:", -G.vd->far, G.vd->far, ebone->tail+2, 0);
317
318         /* Convert roll to degrees */
319         ebone->roll *= (180.0F/M_PI);
320         add_numbut(6, NUM|FLO, "Roll:", -G.vd->far, G.vd->far, &ebone->roll, 0);
321
322         do_clever_numbuts("Active Bone", 7, REDRAW);
323
324         /* Convert roll to radians */
325         ebone->roll /= (180.0F/M_PI);
326
327         //      Update our parent
328         if (ebone->parent && ebone->flag & BONE_IK_TOPARENT){
329                 VECCOPY (ebone->parent->tail, ebone->head);
330         }
331
332         //      Update our children if necessary
333         for (child = G.edbo.first; child; child=child->next){
334                 if (child->parent == ebone && child->flag & BONE_IK_TOPARENT){
335                         VECCOPY (child->head, ebone->tail);
336                 }
337         }
338 }
339
340 void select_bone_by_name (bArmature *arm, char *name, int select)
341 {
342         Bone *bone;
343
344         if (!arm)
345                 return;
346
347         for (bone=arm->bonebase.first; bone; bone=bone->next)
348                 if (select_bonechildren_by_name (bone, name, select))
349                         break;
350 }
351
352 static int select_bonechildren_by_name (Bone *bone, char *name, int select)
353 {
354         Bone *curBone;
355
356         if (!strcmp (bone->name, name)){
357                 if (select)
358                         bone->flag |= BONE_SELECTED;
359                 else
360                         bone->flag &= ~BONE_SELECTED;
361                 return 1;
362         }
363
364         for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
365                 if (select_bonechildren_by_name (curBone, name, select))
366                         return 1;
367         }
368
369         return 0;
370 }
371 void selectconnected_armature(void)
372 {
373         EditBone *bone, *curBone, *next;
374
375         if (G.qual & LR_SHIFTKEY)
376                 bone= get_nearest_bone(0);
377         else
378                 bone= get_nearest_bone(1);
379
380         if (!bone)
381                 return;
382
383         /* Select parents */
384         for (curBone=bone; curBone; curBone=next){
385                 if (G.qual & LR_SHIFTKEY){
386                         curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
387                 }
388                 else{
389                         curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
390                 }
391
392                 if (curBone->flag & BONE_IK_TOPARENT)
393                         next=curBone->parent;
394                 else
395                         next=NULL;
396         }
397
398         /* Select children */
399         while (bone){
400                 for (curBone=G.edbo.first; curBone; curBone=next){
401                         next = curBone->next;
402                         if (curBone->parent == bone){
403                                 if (curBone->flag & BONE_IK_TOPARENT){
404                                         if (G.qual & LR_SHIFTKEY)
405                                                 curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
406                                         else
407                                                 curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
408                                         bone=curBone;
409                                         break;
410                                 }
411                                 else{ 
412                                         bone=NULL;
413                                         break;
414                                 }
415                         }
416                 }
417                 if (!curBone)
418                         bone=NULL;
419
420         }
421
422         countall();
423         allqueue (REDRAWVIEW3D, 0);
424
425 }
426
427 void selectconnected_posearmature(void)
428 {
429         Bone *bone, *curBone, *next;
430
431         if (G.qual & LR_SHIFTKEY)
432                 bone= get_nearest_bone(0);
433         else
434                 bone = get_nearest_bone(1);
435
436         if (!bone)
437                 return;
438
439         /* Select parents */
440         for (curBone=bone; curBone; curBone=next){
441                 select_actionchannel_by_name (G.obpose->action, curBone->name, !(G.qual & LR_SHIFTKEY));
442                 if (G.qual & LR_SHIFTKEY)
443                         curBone->flag &= ~BONE_SELECTED;
444                 else
445                         curBone->flag |= BONE_SELECTED;
446
447                 if (curBone->flag & BONE_IK_TOPARENT)
448                         next=curBone->parent;
449                 else
450                         next=NULL;
451         }
452
453         /* Select children */
454         for (curBone=bone->childbase.first; curBone; curBone=next){
455                 selectconnected_posebonechildren (curBone);
456         }
457         
458         countall();
459         allqueue (REDRAWVIEW3D, 0);
460         allqueue (REDRAWACTION, 0);
461 }
462
463 static void selectconnected_posebonechildren (Bone *bone)
464 {
465         Bone *curBone;
466
467         if (!(bone->flag & BONE_IK_TOPARENT))
468                 return;
469
470         select_actionchannel_by_name (G.obpose->action, bone->name, !(G.qual & LR_SHIFTKEY));
471
472         if (G.qual & LR_SHIFTKEY)
473                 bone->flag &= ~BONE_SELECTED;
474         else
475                 bone->flag |= BONE_SELECTED;
476
477         for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
478                 selectconnected_posebonechildren (curBone);
479         }
480 }
481
482
483 char *make_bone_menu (bArmature *arm)
484 {
485         char *menustr=NULL;
486         Bone *curBone;
487         int             size;
488         int             index=0;
489         
490
491         //      Count the bones
492         size = (count_bones (arm, 0xFFFFFFFF, 1)*48) + 256;
493         menustr = MEM_callocN(size, "bonemenu");
494
495         sprintf (menustr, "Select Bone%%t");
496
497         for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
498                 make_bone_menu_children (curBone, menustr, &index);
499         }
500
501         return menustr;
502 }
503
504 static void make_bone_menu_children (Bone *bone, char *str, int *index)
505 {
506         Bone *curBone;
507
508         sprintf (str, "%s|%s%%x%d", str, bone->name, *index);
509         (*index) ++;
510
511         for (curBone=bone->childbase.first; curBone; curBone=curBone->next)
512                 make_bone_menu_children (curBone, str, index);
513 }
514
515 void free_editArmature(void)
516 {
517
518         /*      Clear the editbones list */
519         if (G.edbo.first){
520                 BLI_freelistN (&G.edbo);
521         }
522 }
523
524 static EditBone * get_nearest_editbonepoint (int findunsel, int *selmask){
525         EditBone        *ebone;
526         GLuint          buffer[MAXPICKBUF];
527         short           hits;
528         int              i, takeNext=0;
529         int             sel;
530         unsigned int    hitresult, hitbone, firstunSel=-1;
531
532         glInitNames();
533         hits=selectprojektie(buffer, 0, 0, 0, 0);
534
535         /* See if there are any selected bones in this group */
536         if (hits){
537                 for (i=0; i< hits; i++){
538                         hitresult = buffer[3+(i*4)];
539                         if (!(hitresult&BONESEL_NOSEL)){
540
541                                 /* Determine which points are selected */
542                                 hitbone = hitresult & ~(BONESEL_ROOT|BONESEL_TIP);
543
544                                 /* Determine what the current bone is */
545                                 ebone = BLI_findlink(&G.edbo, hitbone);
546
547                                 /* See if it is selected */
548                                 sel = 0;
549                                 if ((hitresult & (BONESEL_TIP|BONESEL_ROOT)) == (BONESEL_TIP|BONESEL_ROOT))
550                                         sel = (ebone->flag & (BONE_TIPSEL| BONE_ROOTSEL)) == (BONE_TIPSEL|BONE_ROOTSEL) ? 1 : 0;
551                                 else if (hitresult & BONESEL_TIP)
552                                         sel |= ebone->flag & BONE_TIPSEL;
553                                 else if (hitresult & BONESEL_ROOT)
554                                         sel |= ebone->flag & BONE_ROOTSEL;
555                                 if (!findunsel)
556                                         sel = !sel;
557                         
558                                 if (sel)
559                                         takeNext=1;
560                                 else{
561                                         if (firstunSel == -1)
562                                                 firstunSel = hitresult;
563                                         if (takeNext){
564                                                 *selmask =0;
565                                                 if (hitresult & BONESEL_ROOT)
566                                                         *selmask |= BONE_ROOTSEL;
567                                                 if (hitresult & BONESEL_TIP)
568                                                         *selmask |= BONE_TIPSEL;
569                                                 return ebone;
570                                         }
571                                 }
572                         }
573                 }
574
575                 if (firstunSel != -1){
576                         *selmask = 0;
577                         if (firstunSel & BONESEL_ROOT)
578                                 *selmask |= BONE_ROOTSEL;
579                         if (firstunSel & BONESEL_TIP)
580                                 *selmask |= BONE_TIPSEL;
581                         return BLI_findlink(&G.edbo, firstunSel & ~(BONESEL_ROOT|BONESEL_TIP));
582                 }
583 #if 1
584                 else{
585                         *selmask = 0;
586                         if (buffer[3] & BONESEL_ROOT)
587                                 *selmask |= BONE_ROOTSEL;
588                         if (buffer[3] & BONESEL_TIP)
589                                 *selmask |= BONE_TIPSEL;
590 #if 1
591                         return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP));
592 #else
593                         return NULL;
594 #endif
595                 }
596 #endif
597         }
598
599         *selmask = 0;
600         return NULL;
601 }
602
603 static void * get_nearest_bone (int findunsel){
604         void            *firstunSel=NULL, *data;
605         GLuint          buffer[MAXPICKBUF];
606         short           hits;
607         int              i, takeNext=0;
608         int             sel;
609         unsigned int    hitresult;
610         Bone *bone;
611         EditBone *ebone;
612
613         glInitNames();
614         hits=selectprojektie(buffer, 0, 0, 0, 0);
615
616
617         /* See if there are any selected bones in this group */
618         if (hits){
619                 for (i=0; i< hits; i++){
620                         hitresult = buffer[3+(i*4)];
621                         if (!(hitresult&BONESEL_NOSEL)){
622
623                                 /* Determine which points are selected */
624                                 hitresult &= ~(BONESEL_ROOT|BONESEL_TIP);
625
626                                 /* Determine what the current bone is */
627                                 if (!G.obedit){
628                                         bone = get_indexed_bone(OBACT->data, hitresult);
629                                         if (findunsel)
630                                                 sel = (bone->flag & BONE_SELECTED);
631                                         else
632                                                 sel = !(bone->flag & BONE_SELECTED);                                    
633                                         data = bone;
634                                 }
635                                 else{
636                                         ebone = BLI_findlink(&G.edbo, hitresult);
637                                         if (findunsel)
638                                                 sel = (ebone->flag & BONE_SELECTED);
639                                         else
640                                                 sel = !(ebone->flag & BONE_SELECTED);
641                                         
642                                         data = ebone;
643                                 }
644                                 
645                                 if (sel)
646                                         takeNext=1;
647                                 else{
648                                         if (!firstunSel)
649                                                 firstunSel=data;
650                                         if (takeNext)
651                                                 return data;
652                                 }
653                         }
654                 }
655
656                 if (firstunSel)
657                         return firstunSel;
658 #if 1
659                 else{
660 #if 1
661                         if (G.obedit)
662                                 return BLI_findlink(&G.edbo, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP));
663                         else
664                                 return get_indexed_bone(OBACT->data, buffer[3] & ~(BONESEL_ROOT|BONESEL_TIP));
665 #else
666                         return NULL;
667 #endif
668                 }
669 #endif
670         }
671
672         return NULL;
673 }
674
675 void delete_armature(void)
676 {
677         EditBone        *curBone, *next;
678         
679         TEST_EDITARMATURE;
680         if(okee("Erase selected")==0) return;
681         
682         for (curBone=G.edbo.first;curBone;curBone=next){
683                 next=curBone->next;
684                 if (curBone->flag&BONE_SELECTED)
685                         delete_bone(curBone);
686         }
687         
688         
689         allqueue(REDRAWVIEW3D, 0);
690         allqueue(REDRAWBUTSEDIT, 0);
691         allqueue(REDRAWBUTSCONSTRAINT, 0);
692         countall();
693 }
694
695
696 static void delete_bone(EditBone* exBone)
697 {
698         EditBone        *curBone;
699         bPoseChannel *chan;
700         
701         /*      Find any bones that refer to this bone  */
702         for (curBone=G.edbo.first;curBone;curBone=curBone->next){
703                 if (curBone->parent==exBone){
704                         curBone->parent=exBone->parent;
705                         curBone->flag &= ~BONE_IK_TOPARENT;
706                 }
707         }
708         
709         /*  Erase any associated pose channel */
710         if (G.obedit->pose){
711                 for (chan=G.obedit->pose->chanbase.first; chan; chan=chan->next){
712                         if (!strcmp (chan->name, exBone->name)){
713                                 free_constraints(&chan->constraints);
714                                 BLI_freelinkN (&G.obedit->pose->chanbase, chan);
715                                 break;
716                         }
717                 }
718         }
719
720
721         allqueue(REDRAWBUTSCONSTRAINT, 0);
722         allqueue(REDRAWBUTSEDIT, 0);
723
724         BLI_freelinkN (&G.edbo,exBone);
725 }
726
727 void remake_editArmature(void)
728 {
729         if(okee("Reload Original data")==0) return;
730         
731         make_editArmature();
732         allqueue(REDRAWVIEW3D, 0);
733         allqueue(REDRAWBUTSHEAD, 0);
734         allqueue(REDRAWBUTSCONSTRAINT, 0);
735         allqueue(REDRAWBUTSEDIT, 0);
736 }
737
738 void mouse_armature(void)
739 {
740         EditBone*       nearBone = NULL;
741         int     selmask;
742
743         nearBone=get_nearest_editbonepoint(1, &selmask);
744
745         if (nearBone){
746                 if ((G.qual & LR_SHIFTKEY) && (nearBone->flag & selmask))
747                         nearBone->flag &= ~selmask;
748                 else
749                         nearBone->flag |= selmask;
750
751                 if (!(G.qual & LR_SHIFTKEY)){
752                         deselectall_armature();
753                         nearBone->flag |= selmask;
754                 }
755                 allqueue(REDRAWVIEW3D, 0);
756                 allqueue(REDRAWBUTSEDIT, 0);
757                 allqueue(REDRAWBUTSCONSTRAINT, 0);
758         };
759         countall();
760         rightmouse_transform();
761 }
762
763 void make_editArmature(void)
764 {
765         bArmature       *arm;
766         
767         if (G.obedit==0)
768                 return;
769         
770         free_editArmature();
771         
772         arm= get_armature(G.obedit);
773         if (!arm)
774                 return;
775         
776         make_boneList (&G.edbo, &arm->bonebase,NULL);
777 }
778
779 static void editbones_to_armature (ListBase *list, Object *ob)
780 {
781         bArmature *arm;
782         EditBone *eBone;
783         Bone    *newBone;
784
785         arm = get_armature(ob);
786         if (!list)
787                 return;
788         if (!arm)
789                 return;
790
791         free_bones(arm);
792         
793
794         /*      Copy the bones from the editData into the armature*/
795         for (eBone=list->first;eBone;eBone=eBone->next){
796                 newBone=MEM_callocN (sizeof(Bone), "bone");
797                 eBone->temp= newBone;   /* Associate the real Bones with the EditBones */
798                 
799                 strcpy (newBone->name, eBone->name);
800                 memcpy (newBone->head, eBone->head, sizeof(float)*3);
801                 memcpy (newBone->tail, eBone->tail, sizeof(float)*3);
802                 newBone->flag=eBone->flag &~(BONE_SELECTED|BONE_HILIGHTED);
803 //              newBone->roll=eBone->roll;
804                 newBone->roll = 0.0F;
805
806                 /*      >>>>> FIXME: This isn't a very good system: a lot of
807                                         pointless copying involved.  To be investigated
808                                         once things are working better.
809                 */
810
811                 newBone->weight = eBone->weight;
812                 newBone->dist = eBone->dist;
813                 memcpy (newBone->loc, eBone->loc, sizeof(eBone->loc));
814                 memcpy (newBone->dloc, eBone->dloc, sizeof(eBone->dloc));
815 /*              memcpy (newBone->orig, eBone->orig, sizeof(eBone->orig));*/
816                 memcpy (newBone->size, eBone->size, sizeof(eBone->size));
817                 memcpy (newBone->dsize, eBone->dsize, sizeof(eBone->dsize));
818                 memcpy (newBone->quat, eBone->quat, sizeof(eBone->quat));
819                 memcpy (newBone->dquat, eBone->dquat, sizeof(eBone->dquat));
820                 memcpy (newBone->obmat, eBone->obmat, sizeof(eBone->obmat));
821         }
822
823         /*      Fix parenting in a separate pass to ensure ebone->bone connections
824                 are valid at this point */
825         for (eBone=list->first;eBone;eBone=eBone->next){
826                 newBone= (Bone*) eBone->temp;
827                 if (eBone->parent){
828                         newBone->parent=(Bone*) eBone->parent->temp;
829                         BLI_addtail (&newBone->parent->childbase,newBone);
830
831                         {
832                                 float M_boneRest[4][4];
833                                 float M_parentRest[4][4];
834                                 float iM_parentRest[4][4];
835                                 float   delta[3];
836                         
837                                 /* Get the parent's global matrix (rotation only)*/
838                                 VecSubf (delta, eBone->parent->tail, eBone->parent->head);
839                                 make_boneMatrixvr(M_parentRest, delta, eBone->parent->roll);
840
841                                 /* Get this bone's global matrix (rotation only)*/
842                                 VecSubf (delta, eBone->tail, eBone->head);
843                                 make_boneMatrixvr(M_boneRest, delta, eBone->roll);
844
845                                 /* Invert the parent matrix */
846                                 Mat4Invert (iM_parentRest, M_parentRest);
847
848                                 /* Get the new head and tail */
849                                 VecSubf (newBone->head, eBone->head, eBone->parent->tail);
850                                 VecSubf (newBone->tail, eBone->tail, eBone->parent->tail);
851
852                                 Mat4MulVecfl(iM_parentRest, newBone->head);
853                                 Mat4MulVecfl(iM_parentRest, newBone->tail);
854         
855
856                         }
857
858                 }
859                 /*      ...otherwise add this bone to the armature's bonebase */
860                 else
861                         BLI_addtail (&arm->bonebase,newBone);
862         }
863
864         /* Make a pass through the new armature to fix rolling */
865         fix_bonelist_roll (&arm->bonebase, list);
866         /* Get rid of pose channels that may have belonged to deleted bones */
867         collect_pose_garbage(ob);
868         /* Ensure all bones have channels */
869         apply_pose_armature(arm, ob->pose, 0);
870
871         /* Calculate and cache the inverse restposition matrices (needed for deformation)*/
872         precalc_bonelist_irestmats(&arm->bonebase);
873 }
874
875
876 void load_editArmature(void)
877 {
878         bArmature               *arm;
879
880         arm=get_armature(G.obedit);
881         if (!arm)
882                 return;
883         
884 #if 1
885         editbones_to_armature(&G.edbo, G.obedit);
886 #else
887         free_bones(arm);
888         
889
890         /*      Copy the bones from the editData into the armature*/
891         for (eBone=G.edbo.first;eBone;eBone=eBone->next){
892                 newBone=MEM_callocN (sizeof(Bone), "bone");
893                 eBone->temp= newBone;   /* Associate the real Bones with the EditBones */
894                 
895                 strcpy (newBone->name, eBone->name);
896                 memcpy (newBone->head, eBone->head, sizeof(float)*3);
897                 memcpy (newBone->tail, eBone->tail, sizeof(float)*3);
898                 newBone->flag=eBone->flag &~(BONE_SELECTED|BONE_HILIGHTED);
899         //      newBone->roll=eBone->roll;
900                 newBone->roll = 0.0F;
901
902                 /*      >>>>> FIXME: This isn't a very good system: a lot of
903                                         pointless copying involved.  To be investigated
904                                         once things are working better.
905                 */
906
907                 newBone->weight = eBone->weight;
908                 newBone->dist = eBone->dist;
909                 memcpy (newBone->loc, eBone->loc, sizeof(eBone->loc));
910                 memcpy (newBone->dloc, eBone->dloc, sizeof(eBone->dloc));
911 /*              memcpy (newBone->orig, eBone->orig, sizeof(eBone->orig));*/
912                 memcpy (newBone->size, eBone->size, sizeof(eBone->size));
913                 memcpy (newBone->dsize, eBone->dsize, sizeof(eBone->dsize));
914                 memcpy (newBone->quat, eBone->quat, sizeof(eBone->quat));
915                 memcpy (newBone->dquat, eBone->dquat, sizeof(eBone->dquat));
916                 memcpy (newBone->obmat, eBone->obmat, sizeof(eBone->obmat));
917         }
918
919         /*      Fix parenting in a separate pass to ensure ebone->bone connections
920                 are valid at this point */
921         for (eBone=G.edbo.first;eBone;eBone=eBone->next){
922                 newBone= (Bone*) eBone->temp;
923                 if (eBone->parent){
924                         newBone->parent=(Bone*) eBone->parent->temp;
925                         BLI_addtail (&newBone->parent->childbase,newBone);
926
927                         {
928                                 float M_boneRest[4][4];
929                                 float M_parentRest[4][4];
930                                 float M_relativeBone[4][4];
931                                 float iM_parentRest[4][4];
932                                 float   delta[3];
933                         
934                                 /* Get the parent's global matrix (rotation only)*/
935                                 VecSubf (delta, eBone->parent->tail, eBone->parent->head);
936                                 make_boneMatrixvr(M_parentRest, delta, eBone->parent->roll);
937
938                                 /* Get this bone's global matrix (rotation only)*/
939                                 VecSubf (delta, eBone->tail, eBone->head);
940                                 make_boneMatrixvr(M_boneRest, delta, eBone->roll);
941
942                                 /* Invert the parent matrix */
943                                 Mat4Invert (iM_parentRest, M_parentRest);
944
945                                 /* Get the new head and tail */
946                                 VecSubf (newBone->head, eBone->head, eBone->parent->tail);
947                                 VecSubf (newBone->tail, eBone->tail, eBone->parent->tail);
948
949                                 Mat4MulVecfl(iM_parentRest, newBone->head);
950                                 Mat4MulVecfl(iM_parentRest, newBone->tail);
951         
952
953                         }
954
955                 }
956                 /*      ...otherwise add this bone to the armature's bonebase */
957                 else
958                         BLI_addtail (&arm->bonebase,newBone);
959         }
960
961         /* Make a pass through the new armature to fix rolling */
962         fix_bonelist_roll (&arm->bonebase, &G.edbo);
963
964         /* Get rid of pose channels that may have belonged to deleted bones */
965         collect_pose_garbage(G.obedit);
966 #endif
967 }
968
969 static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
970 {
971         Bone *curBone;
972         EditBone *ebone;
973
974         for (curBone=bonelist->first; curBone; curBone=curBone->next){
975                 
976                 /* Fix this bone's roll */
977 #if 1
978                 {
979                         float premat[4][4];
980                         float postmat[4][4];
981                         float difmat[4][4];
982                         float imat[4][4];
983                         float delta[3];
984
985                         /* Find the associated editbone */
986                         for (ebone = editbonelist->first; ebone; ebone=ebone->next)
987                                 if ((Bone*)ebone->temp == curBone)
988                                         break;
989                         
990                                 if (ebone){
991                                         /* Get the premat */
992                                         VecSubf (delta, ebone->tail, ebone->head);
993                                         make_boneMatrixvr(premat, delta, ebone->roll);
994                                         
995                                         /* Get the postmat */
996                                         get_objectspace_bone_matrix(curBone, postmat, 1, 0);
997                                         postmat[3][0]=postmat[3][1]=postmat[3][2]=0.0F;
998 #if 1
999                                         Mat4Invert (imat, premat);
1000                                         Mat4MulMat4 (difmat, postmat, imat);
1001 #else
1002                                         Mat4Invert (imat, postmat);
1003                                         Mat4MulMat4 (difmat, premat, imat);
1004 #endif
1005 #if 0
1006                                         printf ("Bone %s\n", curBone->name);
1007                                         printmatrix4 ("premat", premat);
1008                                         printmatrix4 ("postmat", postmat);
1009                                         printmatrix4 ("difmat", difmat);
1010                                         printf ("Roll = %f\n",  (-atan(difmat[2][0]/difmat[2][2]) * (180.0/M_PI)));
1011 #endif
1012                                         curBone->roll = -atan(difmat[2][0]/difmat[2][2]);
1013                                         
1014                                         if (difmat[0][0]<0)
1015                                                 curBone->roll +=M_PI;
1016                                         
1017                                 }
1018                 }
1019 #endif
1020                 
1021                 fix_bonelist_roll (&curBone->childbase, editbonelist);
1022         }
1023 }
1024
1025 void make_bone_parent(void)
1026 {
1027 /*      error ("Bone Parenting not yet implemented");   */
1028         return;
1029 }
1030
1031 static void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
1032 {
1033         EditBone        *eBone;
1034         Bone            *curBone;
1035         
1036         for (curBone=bones->first; curBone; curBone=curBone->next){
1037                 eBone=MEM_callocN(sizeof(EditBone),"make_editbone");
1038                 
1039                 /*      Copy relevant data from bone to eBone */
1040                 eBone->parent=parent;
1041                 strcpy (eBone->name, curBone->name);
1042                 eBone->flag = curBone->flag & ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
1043
1044                 /* Print bone matrix before and after */
1045
1046                 get_bone_root_pos(curBone, eBone->head, 0);
1047                 get_bone_tip_pos(curBone, eBone->tail, 0);
1048 //              eBone->roll=curBone->roll;
1049                 eBone->roll=0;
1050
1051 #if 1
1052                 {
1053                         float delta[3];
1054                         float premat[4][4];
1055                         float postmat[4][4];
1056                         float imat[4][4];
1057                         float difmat[4][4];
1058
1059                         VecSubf (delta, eBone->tail, eBone->head);
1060                         make_boneMatrixvr(postmat, delta, eBone->roll);
1061
1062                         get_objectspace_bone_matrix(curBone, premat, 1, 0);
1063
1064 #if 0
1065                         Mat4Invert (imat, premat);
1066                         Mat4MulMat4 (difmat, postmat, imat);
1067 #else
1068                         Mat4Invert (imat, postmat);
1069                         Mat4MulMat4 (difmat, premat, imat);
1070 #endif
1071 #if 0
1072                         printf ("Bone %s\n", curBone->name);
1073                         printmatrix4 ("diffmat", difmat);
1074                         printf ("Roll : atan of %f / %f = %f\n", difmat[2][0], difmat[2][2], (float)atan(difmat[2][0]/difmat[2][2])*(180.0F/M_PI));
1075 #endif
1076                         eBone->roll = atan(difmat[2][0]/difmat[2][2]);
1077
1078                          if (difmat[0][0]<0)
1079                                 eBone->roll +=M_PI;
1080                 }
1081 #endif          
1082                 eBone->dist= curBone->dist;
1083                 eBone->weight= curBone->weight;
1084                 memcpy (eBone->loc, curBone->loc, sizeof(curBone->loc));
1085                 memcpy (eBone->dloc, curBone->dloc, sizeof(curBone->dloc));
1086                 /*              memcpy (eBone->orig, curBone->orig, sizeof(curBone->orig));*/
1087                 memcpy (eBone->size, curBone->size, sizeof(curBone->size));
1088                 memcpy (eBone->dsize, curBone->dsize, sizeof(curBone->dsize));
1089                 memcpy (eBone->quat, curBone->quat, sizeof(curBone->quat));
1090                 memcpy (eBone->dquat, curBone->dquat, sizeof(curBone->dquat));
1091                 memcpy (eBone->obmat, curBone->obmat, sizeof(curBone->obmat));
1092                 
1093
1094                 BLI_addtail (list, eBone);
1095                 
1096                 /*      Add children if necessary */
1097                 if (curBone->childbase.first) 
1098                         make_boneList (list, &curBone->childbase, eBone);
1099         }
1100         
1101
1102 }
1103
1104 #if 0
1105 static EditVert*         add_armatureVert (float *loc)
1106 {
1107         EditVert*       vert=NULL;
1108
1109         vert = MEM_callocN (sizeof (EditVert), "armaturevert");
1110         if (vert){
1111                 VECCOPY (vert->co, loc);
1112                 BLI_addtail (&G.edve,vert);
1113         }
1114
1115         return vert;
1116
1117 }
1118
1119 static EditVert* get_armatureVert (float *loc)
1120 {
1121         EditVert*       vert;
1122
1123         for (vert=G.edve.first;vert;vert=vert->next){
1124                 if ((vert->co[0]==loc[0])&&(vert->co[1]==loc[1])&&(vert->co[2]==loc[2])){
1125                         return (vert);
1126                 }
1127         }
1128
1129         return add_armatureVert (loc);
1130 }
1131 #endif
1132
1133 void draw_armature(Object *ob)
1134 {
1135         bArmature       *arm;
1136         Bone            *bone;
1137         EditBone        *eBone;
1138         unsigned int    index;
1139         float           delta[3],offset[3];
1140         float           bmat[4][4];
1141         float   length;
1142         
1143         if (ob==NULL) return;
1144         
1145         arm= ob->data; 
1146         if (arm==NULL) return;
1147
1148         if (!(ob->lay & G.vd->lay))
1149                 return;
1150
1151         if (arm->flag & ARM_DRAWXRAY) {
1152                 if(G.zbuf) glDisable(GL_DEPTH_TEST);
1153         }
1154
1155         /* If we're in editmode, draw the Global edit data */
1156         if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
1157                 cpack (0x000000);
1158                 
1159                 arm->flag |= ARM_EDITMODE;
1160                 for (eBone=G.edbo.first, index=0; eBone; eBone=eBone->next, index++){
1161                         if (ob==G.obedit){
1162         //                      if ((eBone->flag&(BONE_TIPSEL | BONE_ROOTSEL))==(BONE_TIPSEL|BONE_ROOTSEL))
1163         //                              cpack (B_YELLOW);
1164         //                      else
1165                                         cpack (B_PURPLE);
1166                         }
1167                         else cpack (0x000000);
1168                         
1169                         glPushMatrix();
1170                         
1171                         /*      Compose the parent transforms (i.e. their translations) */
1172                         VECCOPY (offset,eBone->head);
1173
1174                         glTranslatef (offset[0],offset[1],offset[2]);
1175                         
1176                         delta[0]=eBone->tail[0]-eBone->head[0]; 
1177                         delta[1]=eBone->tail[1]-eBone->head[1]; 
1178                         delta[2]=eBone->tail[2]-eBone->head[2];
1179                         
1180                         length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] +delta[2]*delta[2]);
1181
1182                         make_boneMatrixvr(bmat, delta, eBone->roll);
1183                         glMultMatrixf (bmat);
1184                         draw_bone (arm->flag, eBone->flag, index, eBone->name, length);
1185
1186                         glPopMatrix();
1187                         if (eBone->parent){
1188                                 glLoadName (-1);
1189                                 setlinestyle(3);
1190                                 
1191                                 glBegin(GL_LINES);
1192                                 glVertex3fv(eBone->parent->tail);
1193                                 glVertex3fv(eBone->head);
1194                                 glEnd();
1195
1196                                 setlinestyle(0);
1197                         }
1198                 };
1199                 arm->flag &= ~ARM_EDITMODE;
1200                 cpack (B_YELLOW);
1201                 
1202         }
1203         else{
1204                 /*      Draw hierarchical bone list (non-edit data) */
1205
1206                 /* Ensure we're using the mose recent pose */
1207                 if (!ob->pose)
1208                         ob->pose=MEM_callocN (sizeof(bPose), "pose");
1209
1210 #if 1   /* Activate if there are problems with action lag */
1211                 apply_pose_armature(arm, ob->pose, 0);
1212                 where_is_armature (ob);
1213 #endif
1214
1215                 if (G.obpose == ob){
1216                         arm->flag |= ARM_POSEMODE;
1217 #if 0   /* Depreciated interactive ik goal drawing */
1218                         if (arm->chainbase.first){
1219                                 glPushMatrix();
1220                                 glTranslatef(((PoseChain*)arm->chainbase.first)->goal[0],
1221                                         ((PoseChain*)arm->chainbase.first)->goal[1],
1222                                         ((PoseChain*)arm->chainbase.first)->goal[2]);
1223                                 drawaxes(1.0);
1224                                 glPopMatrix();
1225                         }
1226 #endif
1227                 }
1228                 index = 0;
1229                 for (bone=arm->bonebase.first; bone; bone=bone->next) {
1230                         glPushMatrix();
1231                         draw_bonechildren(bone, arm->flag, &index);
1232                         glPopMatrix();
1233                         if (arm->flag & ARM_POSEMODE)
1234                                 cpack (B_CYAN);
1235                 }
1236
1237                 arm->flag &= ~ARM_POSEMODE; 
1238         }
1239
1240         if (arm->flag & ARM_DRAWXRAY) {
1241                 if(G.zbuf) glEnable(GL_DEPTH_TEST);
1242         }
1243 }
1244
1245 static void draw_boneverti (float x, float y, float z, float size, int flag)
1246 {
1247         GLUquadricObj   *qobj;
1248
1249         size*=0.05;
1250
1251 /*
1252                 Ultimately dots should be drawn in screenspace
1253                 For now we'll just draw them any old way.
1254 */
1255         glPushMatrix();
1256
1257         glTranslatef(x, y, z);
1258
1259         qobj    = gluNewQuadric(); 
1260         gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 
1261         gluPartialDisk( qobj, 0,  1.0F*size, 32, 1, 360.0, 360.0);
1262
1263         glRotatef (90, 0, 1, 0);
1264         gluPartialDisk( qobj, 0,  1.0F*size, 32, 1, 360.0, 360.0);
1265
1266         glRotatef (90, 1, 0, 0);
1267         gluPartialDisk( qobj, 0,  1.0F*size, 32, 1, 360.0, 360.0);
1268
1269         gluDeleteQuadric(qobj);  
1270
1271         glPopMatrix();
1272 }
1273
1274 static void draw_bonechildren (Bone *bone, int flag, unsigned int *index)
1275 {
1276         Bone *cbone;
1277         float   delta[3];
1278         float   length;
1279         float M_objectspacemat[4][4];
1280
1281         if (bone==NULL) return;
1282         
1283         if (flag & ARM_POSEMODE){
1284                 if (bone->flag & BONE_SELECTED)
1285                         cpack (B_CYAN);
1286                 else
1287                         cpack (B_AQUA);
1288         }
1289         
1290         //      Draw a line from our root to the parent's tip
1291         if (bone->parent && !(bone->flag & (BONE_IK_TOPARENT|BONE_HIDDEN)) ){
1292                 float childMat[4][4];
1293                 float boneMat[4][4];
1294                 float tip[3], root[3];
1295                 get_objectspace_bone_matrix(bone->parent, boneMat, 0, 1);
1296                 get_objectspace_bone_matrix(bone, childMat, 1, 1);
1297                 
1298                 VECCOPY (tip, boneMat[3]);
1299                 VECCOPY (root, childMat[3]);
1300                 
1301                 if (flag & ARM_POSEMODE)
1302                         glLoadName (-1);
1303                 setlinestyle(3);
1304                 glBegin(GL_LINES);
1305                 glVertex3fv(tip);
1306                 glVertex3fv(root);
1307                 glEnd();
1308                 setlinestyle(0);
1309         }
1310         
1311         
1312         /* Draw this bone in objectspace */
1313         delta[0]=bone->tail[0]-bone->head[0];
1314         delta[1]=bone->tail[1]-bone->head[1];
1315         delta[2]=bone->tail[2]-bone->head[2];
1316         length = sqrt (delta[0]*delta[0] + delta[1]*delta[1] + delta[2]*delta[2] );
1317         
1318         /* Incorporates offset, rest rotation, user rotation and parent coordinates*/
1319         get_objectspace_bone_matrix(bone, M_objectspacemat, 1, 1);
1320         
1321         if (!(bone->flag & BONE_HIDDEN)){
1322                 glPushMatrix();
1323                 glMultMatrixf(M_objectspacemat);
1324                 
1325                 
1326                 if (flag & ARM_POSEMODE)
1327                         draw_bone(flag, (bone->parent && bone->parent->flag & BONE_HIDDEN) ? (bone->flag & ~BONE_IK_TOPARENT) : (bone->flag), *index, bone->name, length);
1328                 else
1329                         draw_bone(flag, (bone->parent && bone->parent->flag & BONE_HIDDEN) ? (bone->flag & ~BONE_IK_TOPARENT) : (bone->flag), -1, bone->name, length);
1330                 glPopMatrix();
1331         }
1332         (*index)++;
1333
1334         /* Draw the children */
1335         for (cbone= bone->childbase.first; cbone; cbone=cbone->next){
1336                 draw_bonechildren (cbone, flag, index);
1337         }
1338 }
1339
1340 static void draw_bone (int armflag, int boneflag, unsigned int id, char *name, float length)
1341 {
1342         float vec[2];
1343         float   bulge;
1344         float   pointsize;
1345         /* 
1346         FIXME: This routine should probably draw the bones in screenspace using
1347         the projected start & end points of the transformed bone 
1348         */
1349         
1350         pointsize = length;
1351         if (pointsize<0.1)
1352                 pointsize=0.1;
1353
1354         /*      Draw a 3d octahedral bone       */
1355         
1356         bulge=length*0.1;
1357
1358         if (id!=-1)
1359                 glLoadName((GLuint) id );
1360
1361         glPushMatrix();
1362
1363         /*      Draw root point if we have no IK parent */
1364         if (!(boneflag & BONE_IK_TOPARENT)){
1365                 if (id != -1)
1366                         glLoadName (id | BONESEL_ROOT);
1367                 if (armflag & ARM_EDITMODE){
1368                         if (boneflag & BONE_ROOTSEL)
1369                                 cpack (B_YELLOW);
1370                         else
1371                                 cpack (B_PURPLE);
1372                 }
1373                 draw_boneverti (0, 0, 0, pointsize, 0);
1374         }
1375
1376         /*      Draw tip point (for selection only )*/
1377
1378         if (id != -1)
1379                 glLoadName (id | BONESEL_TIP);
1380         
1381         if (armflag & ARM_EDITMODE){
1382                 if (boneflag & BONE_TIPSEL)
1383                         cpack (B_YELLOW);
1384                 else
1385                         cpack (B_PURPLE);
1386         }
1387         
1388         draw_boneverti (0, length, 0, pointsize, 0);
1389
1390         if (id != -1){
1391                 if (armflag & ARM_POSEMODE)
1392                         glLoadName((GLuint) id);
1393                 else{
1394 #if 1   /* Bones not selectable in editmode */  
1395                         glLoadName((GLuint) -1);
1396 #else
1397                         glLoadName ((GLuint) id|BONESEL_TIP|BONESEL_ROOT);
1398 #endif
1399                 }
1400         }
1401         
1402         
1403         if (armflag & ARM_EDITMODE){
1404                 if (boneflag & BONE_SELECTED)
1405                         cpack (B_YELLOW);
1406                 else
1407                         cpack (B_PURPLE);
1408         }
1409         
1410         /*      Draw additional axes */
1411         if (armflag & ARM_DRAWAXES){
1412                 drawaxes(length*0.25F);
1413         }
1414         
1415         /*      Section 1*/
1416         glBegin(GL_LINE_STRIP);
1417         vec[0]= vec[1]= 0;
1418         glVertex2fv(vec);
1419         
1420         vec[0]= -bulge; vec[1]= bulge;
1421         glVertex2fv(vec);
1422         
1423         vec[0]= 0; vec[1]= length;
1424         glVertex2fv(vec);
1425         
1426         vec[0]= bulge; vec[1]= bulge;
1427         glVertex2fv(vec);
1428         
1429         vec[0]= 0; vec[1]= 0;
1430         glVertex2fv(vec);
1431         glEnd();
1432         
1433         /*      Section 2*/
1434         glRotatef(90,0,1,0);
1435         glBegin(GL_LINE_STRIP);
1436         vec[0]= vec[1]= 0;
1437         glVertex2fv(vec);
1438         
1439         vec[0]= -bulge; vec[1]= bulge;
1440         glVertex2fv(vec);
1441         
1442         vec[0]= 0; vec[1]= length;
1443         glVertex2fv(vec);
1444         
1445         vec[0]= bulge; vec[1]= bulge;
1446         glVertex2fv(vec);
1447         
1448         vec[0]= 0; vec[1]= 0;
1449         glVertex2fv(vec);
1450         glEnd();
1451         
1452         /*      Square*/
1453         glTranslatef (0,bulge,0);
1454         glRotatef(45,0,1,0);
1455         glRotatef(90,1,0,0);
1456         glBegin(GL_LINE_STRIP);
1457         
1458         vec[0]= -bulge*.707;vec[1]=-bulge*.707;
1459         glVertex2fv(vec);
1460         
1461         vec[0]= bulge*.707;vec[1]= -bulge*.707;
1462         glVertex2fv(vec);
1463         
1464         vec[0]= bulge*.707;vec[1]= bulge*.707;
1465         glVertex2fv(vec);
1466         
1467         vec[0]= -bulge*.707;vec[1]= bulge*.707;
1468         glVertex2fv(vec);
1469         
1470         vec[0]= vec[1]= -bulge*.707;
1471         glVertex2fv(vec);
1472         glEnd();
1473         
1474
1475         glPopMatrix();
1476
1477         /*      Draw the bone name */
1478         if (armflag & ARM_DRAWNAMES){
1479                 glRasterPos3f(0,  length/2.0,  0);
1480                 BMF_DrawString(G.font, " ");
1481                 BMF_DrawString(G.font, name);
1482         }
1483 }
1484
1485
1486
1487 void add_primitiveArmature(int type)
1488 {
1489         if(G.scene->id.lib) return;
1490         
1491         /* this function also comes from an info window */
1492         if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
1493         if(G.vd==NULL) return;
1494         
1495         check_editmode(OB_ARMATURE);
1496         
1497         /* If we're not the "obedit", make a new object and enter editmode */
1498         if(G.obedit==NULL) {
1499                 add_object(OB_ARMATURE);
1500                 base_init_from_view3d(BASACT, G.vd);
1501                 G.obedit= BASACT->object;
1502                 
1503                 where_is_object(G.obedit);
1504                 
1505                 make_editArmature();
1506                 setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
1507         }
1508         
1509         switch (type){
1510         default:
1511                 add_bone_input (G.obedit);      
1512                 break;
1513         };
1514         
1515         countall();
1516         allqueue(REDRAWVIEW3D, 0);
1517         allqueue(REDRAWBUTSEDIT, 0);
1518         allqueue(REDRAWBUTSHEAD, 0);
1519         allqueue(REDRAWBUTSCONSTRAINT, 0);
1520         allqueue(REDRAWNLA, 0);
1521 }
1522
1523 static void add_bone_input (Object *ob)
1524 /*
1525         FUNCTION: 
1526         Creates a bone chain under user input.
1527         As the user clicks to accept each bone,
1528         a new bone is started as the child and IK
1529         child of the previous bone.  Pressing ESC
1530         cancels the current bone and leaves bone
1531         adding mode.
1532
1533 */
1534 {
1535         float           *cursLoc, cent[3], dx, dy;
1536         float           mat[3][3], curs[3],     cmat[3][3], imat[3][3], rmat[4][4], itmat[4][4];
1537         short           xo, yo, mval[2], afbreek=0;
1538         short           val;
1539         float           restmat[4][4], tempVec[4];
1540         EditBone        *bone;
1541         EditBone        *parent;
1542         unsigned short          event;
1543         float           angle, scale;
1544         float           length, lengths;
1545         float   newEnd[4];
1546         int                     addbones=1;
1547         float           dvec[3], dvecp[3];
1548         
1549         cursLoc= give_cursor();
1550         
1551         VECCOPY (curs,cursLoc);
1552         
1553         while (addbones>0){
1554                 afbreek=0;
1555                 /*      Create an inverse matrix */
1556                 Mat3CpyMat4(mat, G.obedit->obmat);
1557                 VECCOPY(cent, curs);
1558                 cent[0]-= G.obedit->obmat[3][0];
1559                 cent[1]-= G.obedit->obmat[3][1];
1560                 cent[2]-= G.obedit->obmat[3][2];
1561                 
1562                 Mat3CpyMat4(imat, G.vd->viewmat);
1563                 Mat3MulVecfl(imat, cent);
1564                 
1565                 Mat3MulMat3(cmat, imat, mat);
1566                 Mat3Inv(imat,cmat);
1567                 
1568                 /*      Create a temporary bone */
1569                 bone= MEM_callocN(sizeof(EditBone), "eBone");
1570                 
1571                 /*      If we're the child of something, set that up now */
1572                 if (addbones>1){
1573                         parent=G.edbo.last;
1574                         bone->parent=parent;
1575                         bone->flag|=BONE_IK_TOPARENT;
1576                 }
1577                 
1578                 strcpy (bone->name,"Bone");
1579                 unique_editbone_name (bone->name);
1580         
1581                 BLI_addtail(&G.edbo, bone);
1582         
1583                 bone->flag |= BONE_QUATROT;
1584                 bone->flag |= (BONE_SELECTED);
1585                 deselectall_armature();
1586                 bone->flag |= BONE_SELECTED|BONE_HILIGHTED|BONE_TIPSEL|BONE_ROOTSEL;
1587                 
1588                 bone->weight= 1.0F;
1589                 bone->dist= 1.0F;
1590
1591                 /*      Project cursor center to screenspace. */
1592                 getmouseco_areawin(mval);
1593                 xo= mval[0];
1594                 yo= mval[1];
1595                 window_to_3d(dvecp, xo, yo);
1596
1597                 while (1) {
1598
1599                         getmouseco_areawin(mval);
1600                         window_to_3d(dvec, mval[0], mval[1]);
1601
1602                         scale=1000;
1603
1604                         dx=     ((float)mval[0]-(float)xo)*scale;
1605                         dy= ((float)mval[1]-(float)yo)*scale;
1606         
1607                         /*              Calc bone length*/
1608                         lengths= sqrt((dx*dx)+(dy*dy));
1609                         length = sqrt(((dvec[0]-dvecp[0])*(dvec[0]-dvecp[0]))+((dvec[1]-dvecp[1])*(dvec[1]-dvecp[1]))+((dvec[2]-dvecp[2])*(dvec[2]-dvecp[2])));
1610
1611                         /*              Find rotation around screen normal */
1612                         if (lengths>0.0F) {
1613                                 angle= acos(dy/lengths);
1614                                 if (dx<0.0F)
1615                                         angle*= -1.0F;
1616                         }
1617                         else angle= 0.0F;
1618                         
1619                         /*              FIXME:  Is there a blender-defined way of making rot and trans matrices? */
1620                         rmat[0][0]= cos (angle);
1621                         rmat[0][1]= -sin (angle);
1622                         rmat[0][2]= 0.0F;
1623                         rmat[0][3]= 0.0F;
1624                         rmat[1][0]= sin (angle);
1625                         rmat[1][1]= cos (angle);
1626                         rmat[1][2]= 0.0F;
1627                         rmat[1][3]= 0.0F;
1628                         rmat[2][0]= 0.0F;
1629                         rmat[2][1]= 0.0F;
1630                         rmat[2][2]= 1.0F;
1631                         rmat[2][3]= 0.0F;
1632                         rmat[3][0]= cent[0];
1633                         rmat[3][1]= cent[1];
1634                         rmat[3][2]= cent[2];
1635                         rmat[3][3]= 1.0F;
1636                         
1637                         /*              Rotate object's inversemat by the bone's rotation
1638                         to get the coordinate space of the bone */
1639                         Mat4CpyMat3     (itmat, imat);
1640                         Mat4MulMat4 (restmat, rmat, itmat);
1641                         
1642                         /*      Find the bone head */
1643                         tempVec[0]=0; tempVec[1]=0.0F; tempVec[2]=0.0F; tempVec[3]=1.0F;
1644                         Mat4MulVec4fl (restmat, tempVec);
1645                         VECCOPY (bone->head, tempVec);
1646                         
1647                         /*      Find the bone tail */
1648                         tempVec[0]=0; tempVec[1]=length; tempVec[2]=0.0F; tempVec[3]=1.0F;
1649                         Mat4MulVec4fl (restmat, tempVec);
1650                         VECCOPY (bone->tail, tempVec);
1651                         
1652                         /*      IF we're a child of something, add the parents' translates      */
1653                         
1654                         /*      Offset of child is new cursor*/
1655
1656                         VECCOPY (newEnd,bone->tail); newEnd[3]=1;
1657
1658                         /*      Set the bone's transformations  */
1659                         Mat4One (bone->obmat);
1660                         bone->size[0]=bone->size[1]=bone->size[2]=1.0F;
1661
1662                         force_draw();
1663                         while(qtest()) {
1664                                 event= extern_qread(&val);
1665                                 if(val) {
1666                                         switch(event) {
1667                                         case ESCKEY:
1668                                         case RIGHTMOUSE:
1669                                                 BLI_freelinkN (&G.edbo,bone);
1670                                                 afbreek=1;
1671                                                 addbones=0;
1672                                                 break;
1673                                         case LEFTMOUSE:
1674                                         case MIDDLEMOUSE:
1675                                         case SPACEKEY:
1676                                         case RETKEY:
1677                                                 afbreek= 1;
1678                                                                                         
1679                                                 Mat4MulVec4fl (G.obedit->obmat,newEnd);
1680                                                 
1681                                                 curs[0]=newEnd[0];
1682                                                 curs[1]=newEnd[1];
1683                                                 curs[2]=newEnd[2];
1684                                                 addbones++;
1685                                                 break;
1686                                         }       /*      End of case*/
1687                                 }       /*      End of if (val)*/
1688                                 if(afbreek) break;
1689                         }       /*      Endd of Qtest loop      */
1690
1691                 if(afbreek) break;
1692                 }/*     End of positioning loop (while)*/
1693         }       /*      End of bone adding loop*/
1694         
1695         countall();
1696
1697 }
1698
1699 static void validate_editbonebutton_cb(void *bonev, void *arg2_unused)
1700 {
1701         EditBone *curBone= bonev;
1702         validate_editbonebutton(curBone);
1703 }
1704 static void parnr_to_editbone_cb(void *bonev, void *arg2_unused)
1705 {
1706         EditBone *curBone= bonev;
1707         parnr_to_editbone(curBone);
1708 }
1709 static void attach_bone_to_parent_cb(void *bonev, void *arg2_unused)
1710 {
1711         EditBone *curBone= bonev;
1712         attach_bone_to_parent(curBone);
1713 }
1714
1715 void armaturebuts(void)
1716 {
1717         bArmature       *arm=NULL;
1718         Object          *ob=NULL;
1719         uiBlock         *block=NULL;
1720         char            str[64];
1721         int                     bx=148, by=100;
1722         EditBone        *curBone;
1723         uiBut           *but;
1724         char            *boneString=NULL;
1725         int                     index;
1726
1727         ob= OBACT;
1728         if (ob==NULL) return;
1729         
1730         sprintf(str, "editbuttonswin %d", curarea->win);
1731         block= uiNewBlock (&curarea->uiblocks, str, UI_EMBOSSX, UI_HELV, curarea->win);
1732         
1733         arm= ob->data;
1734         if (arm==NULL) return;
1735         
1736         uiBlockSetCol(block, BUTGREEN);
1737         uiDefButI(block, TOG|BIT|ARM_RESTPOSBIT,REDRAWVIEW3D, "Rest Pos", bx,by,97,20, &arm->flag, 0, 0, 0, 0, "Disable all animation for this object");
1738         uiDefButI(block, TOG|BIT|ARM_DRAWAXESBIT,REDRAWVIEW3D, "Draw Axes", bx,by-46,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone axes");
1739         uiDefButI(block, TOG|BIT|ARM_DRAWNAMESBIT,REDRAWVIEW3D, "Draw Names", bx,by-69,97,20, &arm->flag, 0, 0, 0, 0, "Draw bone names");
1740         uiDefButI(block, TOG|BIT|ARM_DRAWXRAYBIT,REDRAWVIEW3D, "X-Ray", bx,by-92,97,20, &arm->flag, 0, 0, 0, 0, "Draw armature in front of shaded objects");
1741
1742         uiBlockSetCol(block, BUTGREY);
1743         
1744         /* Draw the bone name block */
1745         
1746         bx+=400; by=200;
1747         
1748         if (G.obedit==ob){
1749                 uiDefBut(block, LABEL, 0, "Selected Bones",                                             bx,by,128,18, 0, 0, 0, 0, 0, "");
1750                 by-=20;
1751                 for (curBone=G.edbo.first, index=0; curBone; curBone=curBone->next, index++){
1752                         if (curBone->flag & (BONE_SELECTED)){
1753
1754                                 /* Hide in posemode flag */
1755                                 uiBlockSetCol(block, BUTGREEN);
1756                                 uiDefButI(block, TOG|BIT|BONE_HIDDENBIT, REDRAWVIEW3D, "Hide", bx-50,by,48,18, &curBone->flag, 0, 0, 0, 0, "Toggles display of this bone in posemode");
1757                                 
1758                                 /*      Bone naming button */
1759                                 uiBlockSetCol(block, BUTGREY);
1760                                 strcpy (curBone->oldname, curBone->name);
1761                                 but=uiDefBut(block, TEX, REDRAWVIEW3D, "BO:", bx,by,97,18, &curBone->name, 0, 24, 0, 0, "Change the bone name");
1762                                 uiButSetFunc(but, validate_editbonebutton_cb, curBone, NULL);
1763                                 
1764                                 uiDefBut(block, LABEL, 0, "child of", bx+106,by,100,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
1765
1766                                 boneString = malloc((BLI_countlist(&G.edbo) * 64)+64);
1767                                 build_bonestring (boneString, curBone);
1768                                 
1769                                 curBone->parNr = editbone_to_parnr(curBone->parent);
1770                                 but = uiDefButI(block, MENU,REDRAWVIEW3D, boneString, bx+164,by,97,18, &curBone->parNr, 0.0, 0.0, 0.0, 0.0, "Parent");
1771                                 uiButSetFunc(but, parnr_to_editbone_cb, curBone, NULL);
1772
1773                                 free(boneString);
1774
1775                                 /* IK to parent flag */
1776                                 if (curBone->parent){
1777                                         uiBlockSetCol(block, BUTGREEN);
1778                                         but=uiDefButI(block, TOG|BIT|BONE_IK_TOPARENTBIT, REDRAWVIEW3D, "IK", bx+275,by,32,18, &curBone->flag, 0.0, 0.0, 0.0, 0.0, "IK link to parent");
1779                                         uiButSetFunc(but, attach_bone_to_parent_cb, curBone, NULL);
1780                                 }
1781
1782                                 /* Dist and weight buttons */
1783                                 uiBlockSetCol(block, BUTGREY);
1784                                 uiDefButF(block, NUM,REDRAWVIEW3D, "Dist:", bx+320, by, 110, 18, &curBone->dist, 0.0, 1000.0, 10.0, 0.0, "Bone deformation distance");
1785                                 uiDefButF(block, NUM,REDRAWVIEW3D, "Weight:", bx+438, by, 110, 18, &curBone->weight, 0.0F, 1000.0F, 10.0F, 0.0F, "Bone deformation weight");
1786                                 
1787                                 by-=19; 
1788                         }
1789                 }
1790         }
1791
1792         uiDrawBlock (block);
1793
1794 }
1795
1796 static int editbone_to_parnr (EditBone *bone)
1797 {
1798         EditBone *ebone;
1799         int     index;
1800
1801         for (ebone=G.edbo.first, index=0; ebone; ebone=ebone->next, index++){
1802                 if (ebone==bone)
1803                         return index;
1804         }
1805
1806         return -1;
1807 }
1808
1809 static void parnr_to_editbone(EditBone *bone)
1810 {
1811         if (bone->parNr == -1){
1812                 bone->parent = NULL;
1813                 bone->flag &= ~BONE_IK_TOPARENT;
1814         }
1815         else{
1816                 bone->parent = BLI_findlink(&G.edbo, bone->parNr);
1817                 attach_bone_to_parent(bone);
1818         }
1819 }
1820
1821 static void attach_bone_to_parent(EditBone *bone)
1822 {
1823         EditBone *curbone;
1824
1825         if (bone->flag & BONE_IK_TOPARENT) {
1826
1827         /* See if there are any other bones that refer to the same parent and disconnect them */
1828                 for (curbone = G.edbo.first; curbone; curbone=curbone->next){
1829                         if (curbone!=bone){
1830                                 if (curbone->parent && (curbone->parent == bone->parent) && (curbone->flag & BONE_IK_TOPARENT))
1831                                         curbone->flag &= ~BONE_IK_TOPARENT;
1832                         }
1833                 }
1834
1835         /* Attach this bone to its parent */
1836                 VECCOPY(bone->head, bone->parent->tail);
1837         }
1838
1839 }
1840
1841 static void build_bonestring (char *string, EditBone *bone){
1842         EditBone *curBone;
1843         EditBone *pBone;
1844         int             skip=0;
1845         int             index;
1846
1847         sprintf (string, "Parent%%t| %%x%d", -1);       /* That space is there for a reason */
1848         
1849         for (curBone = G.edbo.first, index=0; curBone; curBone=curBone->next, index++){
1850                 /* Make sure this is a valid child */
1851                 if (curBone != bone){
1852                         skip=0;
1853                         for (pBone=curBone->parent; pBone; pBone=pBone->parent){
1854                                 if (pBone==bone){
1855                                         skip=1;
1856                                         break;
1857                                 }
1858                         }
1859                         
1860                         if (skip)
1861                                 continue;
1862                         
1863                         sprintf (string, "%s|%s%%x%d", string, curBone->name, index);
1864                 }
1865         }
1866 }
1867
1868 static void validate_editbonebutton(EditBone *eBone){
1869         EditBone        *prev;
1870         bAction         *act;
1871         bActionChannel *chan;
1872         Base *base;
1873
1874         /* Separate the bone from the G.edbo */
1875         prev=eBone->prev;
1876         BLI_remlink (&G.edbo, eBone);
1877
1878         /*      Validate the name */
1879         unique_editbone_name (eBone->name);
1880
1881         /* Re-insert the bone */
1882         if (prev)
1883                 BLI_insertlink(&G.edbo, prev, eBone);
1884         else
1885                 BLI_addhead (&G.edbo, eBone);
1886
1887         /* Rename channel if necessary */
1888         if (G.obedit)
1889                 act = G.obedit->action;
1890
1891         if (act && !act->id.lib){
1892                 //      Find the appropriate channel
1893                 for (chan = act->chanbase.first; chan; chan=chan->next){
1894                         if (!strcmp (chan->name, eBone->oldname)){
1895                                 strcpy (chan->name, eBone->name);
1896                         }
1897                 }
1898                 allqueue(REDRAWACTION, 0);
1899         }
1900
1901         /* Update the parenting info of any users */
1902         /*      Yes, I know this is the worst thing you have ever seen. */
1903
1904         for (base = G.scene->base.first; base; base=base->next){
1905                 Object *ob = base->object;
1906
1907                 /* See if an object is parented to this armature */
1908                 if (ob->parent && ob->partype==PARBONE && (ob->parent->type==OB_ARMATURE) && (ob->parent->data == G.obedit->data)){
1909                         if (!strcmp(ob->parsubstr, eBone->oldname))
1910                                 strcpy(ob->parsubstr, eBone->name);
1911                 }
1912         }
1913
1914         exit_editmode(0);       /* To ensure new names make it to the edit armature */
1915
1916 }
1917
1918 void deselectall_armature(void)
1919 /*      Actually, it toggles selection, deselecting
1920         everything if anything is selected */
1921 {
1922         EditBone        *eBone;
1923         int                     sel=1;
1924         
1925         
1926         /*      Determine if there are any selected bones
1927                 And therefore whether we are selecting or deselecting */
1928         for (eBone=G.edbo.first;eBone;eBone=eBone->next){
1929                 if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){
1930                         sel=0;
1931                         break;
1932                 };
1933         };
1934         
1935         /*      Set the flags */
1936         for (eBone=G.edbo.first;eBone;eBone=eBone->next){
1937                 if (sel)
1938                         eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1939                 else
1940                         eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
1941         };
1942         allqueue(REDRAWVIEW3D, 0);
1943         allqueue(REDRAWBUTSEDIT, 0);
1944         allqueue(REDRAWBUTSHEAD, 0);
1945         allqueue(REDRAWBUTSCONSTRAINT, 0);
1946         countall();
1947 }
1948
1949 void join_armature(void)
1950 {
1951         
1952         Object  *ob;
1953         Base    *base, *nextbase;
1954         ListBase eblist;
1955         EditBone *curbone, *next;
1956         float   mat[4][4], imat[4][4];
1957         
1958         /*      Ensure we're not in editmode and that the active object is an armature*/
1959         if(G.obedit) return;
1960         
1961         ob= OBACT;
1962         if(ob->type!=OB_ARMATURE) return;
1963         
1964         /*      Make sure the user wants to continue*/
1965         if(okee("Join selected Armatures")==0) return;
1966         
1967         /*      Put the active armature into editmode and join the bones from the other one*/
1968 #if 1
1969         enter_editmode();
1970 #else
1971         baselist.first=baselist.last=0;
1972         make_boneList(&baselist, &((bArmature*)ob->data)->bonebase, NULL);
1973 #endif
1974         
1975         for (base=FIRSTBASE; base; base=nextbase) {
1976                 nextbase = base->next;
1977                 if (TESTBASE(base)){
1978                         if ((base->object->type==OB_ARMATURE) && (base->object!=ob)){
1979                                 /* Make a list of editbones */
1980                                 eblist.first=eblist.last=0;
1981                                 make_boneList (&eblist, &((bArmature*)base->object->data)->bonebase,NULL);
1982                                 /* Find the difference matrix */
1983                                 Mat4Invert(imat, ob->obmat);
1984                                 Mat4MulMat4(mat, base->object->obmat, imat);
1985                                 
1986                                 /* Copy bones from the object to the edit armature */
1987                                 for (curbone=eblist.first; curbone; curbone=next){
1988                                         next = curbone->next;
1989                                         
1990                                         /* Blank out tranformation data */
1991                                         curbone->loc[0]=curbone->loc[1]=curbone->loc[2]=0.0F;
1992                                         curbone->size[0]=curbone->size[1]=curbone->size[2]=1.0F;
1993                                         curbone->quat[0]=curbone->quat[1]=curbone->quat[2]=curbone->quat[3]=0.0F;
1994                                         
1995                                         unique_editbone_name (curbone->name);
1996                                         
1997                                         /* Transform the bone */
1998                                         {
1999                                                 float premat[4][4];
2000                                                 float postmat[4][4];
2001                                                 float difmat[4][4];
2002                                                 float imat[4][4];
2003                                                 float temp[4][4];
2004                                                 float delta[3];
2005
2006                                                 /* Get the premat */
2007                                                 VecSubf (delta, curbone->tail, curbone->head);
2008                                                 make_boneMatrixvr(temp, delta, curbone->roll);
2009                                                 Mat4MulMat4 (premat, temp, mat);
2010
2011                                                 Mat4MulVecfl(mat, curbone->head);
2012                                                 Mat4MulVecfl(mat, curbone->tail);
2013
2014                                                 /* Get the postmat */
2015                                                 VecSubf (delta, curbone->tail, curbone->head);
2016                                                 make_boneMatrixvr(postmat, delta, curbone->roll);
2017                                                 
2018                                                 /* Find the roll */
2019                                                 Mat4Invert (imat, premat);
2020                                                 Mat4MulMat4 (difmat, postmat, imat);
2021                                                 
2022                                                 curbone->roll -=atan(difmat[2][0]/difmat[2][2]);
2023                                                 
2024                                                 if (difmat[0][0]<0)
2025                                                         curbone->roll +=M_PI;
2026
2027                                         }
2028 #if 1
2029                                         BLI_remlink(&eblist, curbone);
2030                                         BLI_addtail(&G.edbo, curbone);
2031 #else
2032                                         BLI_remlink(&eblist, curbone);
2033                                         BLI_addtail(&baselist, curbone);
2034 #endif
2035                                 }
2036                                 
2037                                 free_and_unlink_base(base);
2038                         }
2039                 }
2040         }
2041         
2042 #if 1
2043         exit_editmode(1);
2044 #else
2045         editbones_to_armature(&baselist, ob);
2046         if (baselist.first){
2047                 BLI_freelistN (&baselist);
2048         }
2049 #endif
2050         allqueue(REDRAWVIEW3D, 0);
2051
2052 }
2053
2054
2055 static int      editbone_name_exists (char *name){
2056         EditBone        *eBone;
2057         
2058         for (eBone=G.edbo.first; eBone; eBone=eBone->next){
2059                 if (!strcmp (name, eBone->name))
2060                         return 1;
2061         }
2062         
2063         return 0;
2064                 
2065 }
2066
2067 static void unique_editbone_name (char *name){
2068         char            tempname[64];
2069         int                     number;
2070         char            *dot;
2071         
2072         
2073         if (editbone_name_exists(name)){
2074                 /*      Strip off the suffix */
2075                 dot=strchr(name, '.');
2076                 if (dot)
2077                         *dot=0;
2078                 
2079                 for (number = 1; number <=999; number++){
2080                         sprintf (tempname, "%s.%03d", name, number);
2081                         if (!editbone_name_exists(tempname)){
2082                                 strcpy (name, tempname);
2083                                 return;
2084                         }
2085                 }
2086         }
2087 }
2088
2089 void extrude_armature(void)
2090 {
2091         EditBone *newbone, *curbone, *first=NULL, *partest;
2092         
2093         TEST_EDITARMATURE;
2094         
2095         
2096         if(okee("Extrude Bone Segments")==0) return;
2097         
2098         /* Duplicate the necessary bones */
2099         for (curbone = G.edbo.first; ((curbone) && (curbone!=first)); curbone=curbone->next){
2100                 if (curbone->flag & (BONE_TIPSEL|BONE_SELECTED)){
2101                         newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
2102                         
2103                         
2104                         VECCOPY (newbone->head, curbone->tail);
2105                         VECCOPY (newbone->tail, newbone->head);
2106                         newbone->parent = curbone;
2107                         newbone->flag = BONE_TIPSEL;
2108                         newbone->flag |= BONE_QUATROT;
2109                         newbone->weight= curbone->weight;
2110                         newbone->dist= curbone->dist;
2111                         Mat4One(newbone->obmat);
2112                         
2113                         /* See if there are any ik children of the parent */
2114                         for (partest = G.edbo.first; partest; partest=partest->next){
2115                                 if ((partest->parent == curbone) && (partest->flag & BONE_IK_TOPARENT))
2116                                         break;
2117                         }
2118                         
2119                         if (!partest)
2120                                 newbone->flag |= BONE_IK_TOPARENT;
2121                         
2122                         strcpy (newbone->name, curbone->name);
2123                         unique_editbone_name(newbone->name);
2124                         
2125                         /* Add the new bone to the list */
2126                         BLI_addtail(&G.edbo, newbone);
2127                         if (!first)
2128                                 first = newbone;
2129                 }
2130                 
2131                 /* Deselect the old bone */
2132                 curbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
2133                 
2134         }
2135         
2136         /* Transform the endpoints */
2137         countall();
2138         transform('g');         
2139         allqueue(REDRAWBUTSEDIT, 0);
2140         allqueue(REDRAWBUTSCONSTRAINT, 0);
2141 }
2142
2143 void addvert_armature(void)
2144 {
2145 /*      
2146         I haven't decided if it will be possible to add bones in this way.
2147         For the moment, we'll use Extrude, or explicit parenting.
2148         */
2149 }
2150
2151
2152
2153
2154
2155 void adduplicate_armature(void)
2156 {
2157         EditBone        *eBone = NULL;
2158         EditBone        *curBone;
2159         EditBone        *firstDup=NULL; /*      The beginning of the duplicated bones in the edbo list */
2160
2161         countall();
2162
2163         /*      Find the selected bones and duplicate them as needed */
2164         for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){
2165                 if (curBone->flag & BONE_SELECTED){
2166
2167                         eBone=MEM_callocN(sizeof(EditBone), "addup_editbone");
2168                         eBone->flag |= BONE_SELECTED;
2169
2170                         /*      Copy data from old bone to new bone */
2171                         memcpy (eBone, curBone, sizeof(EditBone));
2172
2173                         /* Blank out tranformation data */
2174                         eBone->loc[0]=eBone->loc[1]=eBone->loc[2]=0.0F;
2175                         eBone->size[0]=eBone->size[1]=eBone->size[2]=1.0F;
2176                         eBone->quat[0]=eBone->quat[1]=eBone->quat[2]=eBone->quat[3]=0.0F;
2177
2178                         curBone->temp = eBone;
2179                         eBone->temp = curBone;
2180
2181                         unique_editbone_name (eBone->name);
2182                         BLI_addtail (&G.edbo, eBone);
2183                         if (!firstDup)
2184                                 firstDup=eBone;
2185                 }
2186         }
2187
2188         if (eBone){
2189                 /*      Fix the head and tail */        
2190                 if (eBone->parent && !eBone->parent->flag & BONE_SELECTED){
2191                         VecSubf (eBone->tail, eBone->tail, eBone->head);
2192                         VecSubf (eBone->head, eBone->head, eBone->head);
2193                 }
2194         }
2195
2196         /*      Run though the list and fix the pointers */
2197         for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){
2198
2199                 if (curBone->flag & BONE_SELECTED){
2200                         eBone=(EditBone*) curBone->temp;
2201
2202                         /*      If this bone has no parent,
2203                                         Set the duplicate->parent to NULL
2204                         */
2205                         if (!curBone->parent){
2206                                 eBone->parent = NULL;
2207                         }
2208                         /*      If this bone has a parent that IS selected,
2209                                         Set the duplicate->parent to the curBone->parent->duplicate
2210                         */
2211                          else if (curBone->parent->flag & BONE_SELECTED){
2212                                 eBone->parent=(EditBone*) curBone->parent->temp;
2213                         }
2214                         /*      If this bone has a parent that IS not selected,
2215                                         Set the duplicate->parent to the curBone->parent
2216                         */
2217                          else {
2218                                 eBone->parent=(EditBone*) curBone->parent; 
2219                                 eBone->flag &= ~BONE_IK_TOPARENT;
2220                         }
2221                          
2222                 }
2223         } 
2224         
2225         /*      Deselect the old bones and select the new ones */
2226
2227         for (curBone=G.edbo.first; curBone && curBone!=firstDup; curBone=curBone->next){
2228                 curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
2229         }
2230
2231
2232         transform('g');
2233         allqueue(REDRAWBUTSEDIT, 0);
2234         allqueue(REDRAWBUTSCONSTRAINT, 0);
2235 }
2236
2237 /*
2238  *
2239  *      POSING FUNCTIONS: Maybe move these to a separate file at some point
2240  *
2241  *
2242  */
2243
2244
2245 void clear_armature(Object *ob, char mode){
2246         Bone    *curBone;
2247         bArmature       *arm;
2248
2249         arm=get_armature(ob);
2250         
2251         if (!arm)
2252                 return;
2253
2254         for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
2255                 clear_armature_children (curBone, ob->pose, mode);
2256         }
2257
2258         where_is_armature (ob);
2259
2260 }
2261
2262 static void clear_armature_children (Bone *bone, bPose *pose, char mode){
2263         Bone                    *curBone;
2264         bPoseChannel    *chan;
2265         if (!bone)
2266                 return;
2267         
2268         verify_pose_channel (pose, bone->name);
2269         chan=get_pose_channel (pose, bone->name);
2270
2271         if (!chan)
2272                 return;
2273
2274         if (bone->flag & BONE_SELECTED){
2275                 switch (mode){
2276                 case 'r':
2277                         chan->quat[1]=chan->quat[2]=chan->quat[3]=0.0F; chan->quat[0]=1.0F;
2278                         break;
2279                 case 'g':
2280                         chan->loc[0]=chan->loc[1]=chan->loc[2]=0.0F;
2281                         break;
2282                 case 's':
2283                         chan->size[0]=chan->size[1]=chan->size[2]=1.0F;
2284                         break;
2285                         
2286                 }
2287         }
2288
2289         for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
2290                 clear_armature_children (curBone, pose, mode);
2291         }
2292
2293 }
2294
2295 void mousepose_armature(void)
2296 /*
2297         Handles right-clicking for selection
2298         of bones in armature pose modes.
2299 */
2300 {
2301         Bone            *nearBone;
2302
2303         if (!G.obpose)
2304                 return;
2305
2306         nearBone = get_nearest_bone(1);
2307         
2308         if (nearBone){
2309                 if (!(G.qual & LR_SHIFTKEY)){
2310                         deselectall_posearmature(0);
2311                         nearBone->flag|=BONE_SELECTED;
2312                         select_actionchannel_by_name(G.obpose->action, nearBone->name, 1);
2313                 }
2314                 else {
2315                         if (nearBone->flag & BONE_SELECTED){
2316                                 nearBone->flag &= ~BONE_SELECTED;
2317                                 select_actionchannel_by_name(G.obpose->action, nearBone->name, 0);
2318                         }
2319                         else{
2320                                 nearBone->flag |= BONE_SELECTED;
2321                                 select_actionchannel_by_name(G.obpose->action, nearBone->name, 1);
2322                         }
2323                 };
2324         }
2325
2326         allqueue(REDRAWVIEW3D, 0);
2327         allqueue(REDRAWACTION, 0);
2328         allqueue(REDRAWIPO, 0);         /* To force action ipo update */
2329         allqueue(REDRAWBUTSCONSTRAINT, 0);
2330
2331 //      countall();
2332         rightmouse_transform();
2333         
2334 }
2335
2336 void make_trans_bones (char mode)
2337 /*      Used in pose mode       */
2338 {
2339         bArmature               *arm;
2340         Bone                    *curBone;
2341         int                             count=0;
2342
2343         transmain=NULL;
2344
2345         arm=get_armature (G.obpose);
2346         if (!arm)
2347                 return;
2348
2349         if (arm->flag & ARM_RESTPOS){
2350                 notice ("Transformation not possible while Rest Position is enabled");
2351                 return;
2352         }
2353
2354
2355         if (!(G.obpose->lay & G.vd->lay))
2356                 return;
2357
2358
2359         centroid[0]=centroid[1]=centroid[2]=0;
2360
2361         apply_pose_armature(arm, G.obpose->pose, 0);
2362         where_is_armature (G.obpose);
2363
2364         /*      Allocate memory for the transformation record */
2365         tottrans= count_bones (arm, BONE_SELECTED, 0);
2366
2367         if (!tottrans)
2368                 return;
2369
2370         transmain= MEM_callocN(tottrans*sizeof(TransOb), "bonetransmain");
2371
2372         for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
2373                 count = add_trans_bonechildren (G.obpose, curBone, transmain, count, mode);
2374         }
2375         
2376         tottrans=count;
2377         
2378         if (tottrans){
2379                 centroid[0]/=tottrans;
2380                 centroid[1]/=tottrans;
2381                 centroid[2]/=tottrans;
2382                 Mat4MulVecfl (G.obpose->obmat, centroid);
2383         }
2384         else{
2385                 MEM_freeN (transmain);
2386         }
2387         return;
2388
2389 }
2390
2391 static int      count_bones (bArmature *arm, int flagmask, int allbones)
2392 {
2393         int     count=0;
2394         Bone    *curBone;
2395
2396         if (!arm)
2397                 return 0;
2398
2399         for (curBone=arm->bonebase.first; curBone; curBone=curBone->next){
2400                 count = count_bonechildren (curBone, count, flagmask, allbones);
2401         }
2402
2403         return count;
2404
2405 }
2406
2407 static int count_bonechildren (Bone *bone, int incount, int flagmask, int allbones){
2408
2409         Bone    *curBone;
2410
2411         if (!bone)
2412                 return incount;
2413
2414         if (bone->flag & flagmask || flagmask == 0xFFFFFFFF){
2415                 incount++;
2416                 if (!allbones)
2417                         return incount;
2418         }
2419
2420         for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
2421                 incount=count_bonechildren (curBone, incount, flagmask, allbones);
2422         }
2423
2424         return incount;
2425 }
2426
2427
2428 static int add_trans_bonechildren (Object* ob, Bone* bone, TransOb* buffer, int index, char mode)
2429 {
2430         Bone    *curBone;
2431         TransOb *curOb;
2432         float   parmat[4][4], tempmat[4][4];
2433         float tempobmat[4][4];
2434         float vec[3];
2435         if (!bone)
2436                 return index;
2437
2438         
2439         
2440         /* We don't let IK children get "grabbed" */
2441         if (bone->flag & BONE_SELECTED){
2442                 if (!((mode=='g' || mode=='G') && (bone->flag & BONE_IK_TOPARENT))){
2443                         
2444                         get_bone_root_pos (bone, vec, 1);
2445                 
2446                         VecAddf (centroid, centroid, vec);
2447                         
2448                         curOb=&buffer[index];
2449                         
2450                         curOb->ob = ob;
2451                         curOb->rot=NULL;
2452
2453                         curOb->quat= bone->quat;
2454                         curOb->size= bone->size;
2455                         curOb->loc = bone->loc;
2456
2457                         curOb->data = bone; //  FIXME: Dangerous
2458                         
2459                         memcpy (curOb->oldquat, bone->quat, sizeof (bone->quat));
2460                         memcpy (curOb->oldsize, bone->size, sizeof (bone->size));
2461                         memcpy (curOb->oldloc, bone->loc, sizeof (bone->loc));
2462
2463 #if 0
2464                         if (bone->parent)
2465                                 get_objectspace_bone_matrix(bone->parent, tempmat, 1, 1);
2466                         else
2467                                 Mat4One (tempmat);
2468 #else
2469                         /* Get the matrix of this bone minus the usertransform */
2470                         Mat4CpyMat4 (tempobmat, bone->obmat);
2471                         Mat4One (bone->obmat);
2472                         get_objectspace_bone_matrix(bone, tempmat, 1, 1);
2473                         Mat4CpyMat4 (bone->obmat, tempobmat);
2474
2475                         
2476 #endif
2477
2478 #if 1
2479                         Mat4MulMat4 (parmat, tempmat, ob->obmat);       /* Original */
2480
2481                         /* Get world transform */
2482                         get_objectspace_bone_matrix(bone, tempmat, 1, 1);
2483                         if (ob->parent){
2484                                 where_is_object(ob->parent);
2485                                 Mat4MulSerie (tempobmat, ob->parent->obmat, ob->obmat, tempmat, NULL, NULL, NULL, NULL, NULL);
2486                         }
2487                         else
2488                                 Mat4MulSerie (tempobmat, ob->obmat, tempmat, NULL, NULL, NULL, NULL, NULL, NULL);
2489                         Mat3CpyMat4 (curOb->axismat, tempobmat);
2490                         Mat3Ortho(curOb->axismat);
2491
2492 #else
2493                         Mat4MulMat4 (parmat, ob->obmat, tempmat);
2494 #endif
2495                         Mat3CpyMat4 (curOb->parmat, parmat);
2496                         Mat3Inv (curOb->parinv, curOb->parmat);
2497
2498                         Mat3CpyMat4 (curOb->obmat, bone->obmat);
2499                         Mat3Inv (curOb->obinv, curOb->obmat);
2500                         
2501                         index++;
2502                         return index;
2503                 }
2504
2505         }
2506         
2507         /*      Recursively search  */
2508         for (curBone = bone->childbase.first; curBone; curBone=curBone->next){
2509                 index=add_trans_bonechildren (ob, curBone, buffer, index, mode);
2510         }
2511
2512         return index;
2513 }
2514
2515 static void deselect_bonechildren (Bone *bone, int mode)
2516 {
2517         Bone    *curBone;
2518
2519         if (!bone)
2520                 return;
2521
2522         if (mode==0)
2523                 bone->flag &= ~BONE_SELECTED;
2524         else if (!(bone->flag & BONE_HIDDEN))
2525                 bone->flag |= BONE_SELECTED;
2526
2527         select_actionchannel_by_name(G.obpose->action, bone->name, mode);
2528
2529         for (curBone=bone->childbase.first; curBone; curBone=curBone->next){
2530                 deselect_bonechildren(curBone, mode);
2531         }
2532 }
2533
2534
2535 void deselectall_posearmature (int test){
2536         int     selectmode      =       0;
2537         Bone*   curBone;
2538         
2539         /*      Determine if we're selecting or deselecting     */
2540         if (test){
2541                 if (!count_bones (get_armature(G.obpose), BONE_SELECTED, 0))
2542                         selectmode = 1;
2543         }
2544         
2545         /*      Set the flags accordingly       */
2546         for (curBone=get_armature(G.obpose)->bonebase.first; curBone; curBone=curBone->next)
2547                 deselect_bonechildren (curBone, selectmode);
2548         
2549         allqueue(REDRAWVIEW3D, 0);
2550         allqueue(REDRAWACTION, 0);
2551
2552 }
2553
2554 void auto_align_armature(void)
2555 /* Sets the roll value of selected bones so that their zaxes point upwards */
2556 {
2557         EditBone *ebone;
2558         float   xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
2559         float   targetmat[4][4], imat[4][4];
2560         float   curmat[4][4], diffmat[4][4];
2561         float   delta[3];
2562
2563         for (ebone = G.edbo.first; ebone; ebone=ebone->next){
2564                 if (ebone->flag & BONE_SELECTED){
2565                         /* Find the current bone matrix */
2566                         VecSubf(delta, ebone->tail, ebone->head);
2567                         make_boneMatrixvr (curmat, delta, 0.0);
2568                         
2569                         /* Make new matrix based on y axis & z-up */
2570                         VECCOPY (yaxis, curmat[1]);
2571
2572                         Mat4One(targetmat);
2573                         VECCOPY (targetmat[0], xaxis);
2574                         VECCOPY (targetmat[1], yaxis);
2575                         VECCOPY (targetmat[2], zaxis);
2576                         Mat4Ortho(targetmat);
2577
2578                         /* Find the difference between the two matrices */
2579
2580                         Mat4Invert (imat, targetmat);
2581                         Mat4MulMat4(diffmat, curmat, imat);
2582
2583                         ebone->roll = atan(diffmat[2][0]/diffmat[2][2]);
2584                         
2585                 }
2586         }
2587
2588