Blender  V2.59
editarmature.c
Go to the documentation of this file.
00001 /*
00002  * $Id: editarmature.c 38751 2011-07-27 06:55:20Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * Contributor(s): Blender Foundation, 2002-2009 full recode.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <ctype.h>
00034 #include <stdlib.h>
00035 #include <stddef.h>
00036 #include <string.h>
00037 #include <math.h> 
00038 #include <float.h> 
00039 #include <assert.h> 
00040 
00041 
00042 #include "DNA_anim_types.h"
00043 #include "DNA_armature_types.h"
00044 #include "DNA_constraint_types.h"
00045 #include "DNA_meshdata_types.h"
00046 #include "DNA_scene_types.h"
00047 
00048 #include "MEM_guardedalloc.h"
00049 
00050 #include "BLI_blenlib.h"
00051 #include "BLI_math.h"
00052 #include "BLI_utildefines.h"
00053 #include "BLI_editVert.h"
00054 #include "BLI_ghash.h"
00055 
00056 #include "BKE_animsys.h"
00057 #include "BKE_action.h"
00058 #include "BKE_armature.h"
00059 #include "BKE_constraint.h"
00060 #include "BKE_context.h"
00061 #include "BKE_deform.h"
00062 #include "BKE_depsgraph.h"
00063 #include "BKE_DerivedMesh.h"
00064 #include "BKE_global.h"
00065 #include "BKE_idprop.h"
00066 #include "BKE_main.h"
00067 #include "BKE_object.h"
00068 #include "BKE_report.h"
00069 #include "BKE_subsurf.h"
00070 #include "BKE_modifier.h"
00071 #include "DNA_object_types.h"
00072 
00073 #include "BIF_gl.h"
00074 
00075 #include "RNA_access.h"
00076 #include "RNA_define.h"
00077 
00078 #include "WM_api.h"
00079 #include "WM_types.h"
00080 
00081 #include "ED_armature.h"
00082 #include "ED_keyframing.h"
00083 #include "ED_mesh.h"
00084 #include "ED_object.h"
00085 #include "ED_screen.h"
00086 #include "ED_util.h"
00087 #include "ED_view3d.h"
00088 
00089 #include "UI_interface.h"
00090 #include "UI_resources.h"
00091 
00092 #include "armature_intern.h"
00093 #include "meshlaplacian.h"
00094 
00095 #if 0
00096 #include "reeb.h"
00097 #endif
00098 
00099 /* **************** tools on Editmode Armature **************** */
00100 
00101 /* Sync selection to parent for connected children */
00102 void ED_armature_sync_selection(ListBase *edbo)
00103 {
00104         EditBone *ebo;
00105         
00106         for (ebo=edbo->first; ebo; ebo= ebo->next) {
00107                 /* if bone is not selectable, we shouldn't alter this setting... */
00108                 if ((ebo->flag & BONE_UNSELECTABLE) == 0) {
00109                         if ((ebo->flag & BONE_CONNECTED) && (ebo->parent)) {
00110                                 if (ebo->parent->flag & BONE_TIPSEL)
00111                                         ebo->flag |= BONE_ROOTSEL;
00112                                 else
00113                                         ebo->flag &= ~BONE_ROOTSEL;
00114                         }
00115                         
00116                         if ((ebo->flag & BONE_TIPSEL) && (ebo->flag & BONE_ROOTSEL))
00117                                 ebo->flag |= BONE_SELECTED;
00118                         else
00119                                 ebo->flag &= ~BONE_SELECTED;
00120                 }
00121         }                               
00122 }
00123 
00124 void ED_armature_validate_active(struct bArmature *arm)
00125 {
00126         EditBone *ebone= arm->act_edbone;
00127 
00128         if(ebone) { 
00129                 if(ebone->flag & BONE_HIDDEN_A)
00130                         arm->act_edbone= NULL;
00131         }
00132 }
00133 
00134 static void bone_free(bArmature *arm, EditBone *bone)
00135 {
00136         if(arm->act_edbone==bone)
00137                 arm->act_edbone= NULL;
00138 
00139         if(bone->prop) {
00140                 IDP_FreeProperty(bone->prop);
00141                 MEM_freeN(bone->prop);
00142         }
00143 
00144         BLI_freelinkN(arm->edbo, bone);
00145 }
00146 
00147 void ED_armature_edit_bone_remove(bArmature *arm, EditBone *exBone)
00148 {
00149         EditBone *curBone;
00150 
00151         /* Find any bones that refer to this bone */
00152         for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
00153                 if (curBone->parent==exBone) {
00154                         curBone->parent=exBone->parent;
00155                         curBone->flag &= ~BONE_CONNECTED;
00156                 }
00157         }
00158 
00159         bone_free(arm, exBone);
00160 }
00161 
00162 /* context: editmode armature */
00163 EditBone *ED_armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo)
00164 {
00165         EditBone *eboflip= NULL;
00166         char name[32];
00167         
00168         if (ebo == NULL)
00169                 return NULL;
00170         
00171         flip_side_name(name, ebo->name, FALSE);
00172         
00173         for (eboflip= edbo->first; eboflip; eboflip=eboflip->next) {
00174                 if (ebo != eboflip) {
00175                         if (!strcmp (name, eboflip->name)) 
00176                                 break;
00177                 }
00178         }
00179         
00180         return eboflip;
00181 }
00182 
00183 /* helper function for tools to work on mirrored parts.
00184    it leaves mirrored bones selected then too, which is a good indication of what happened */
00185 static void armature_select_mirrored(bArmature *arm)
00186 {
00187         /* Select mirrored bones */
00188         if (arm->flag & ARM_MIRROR_EDIT) {
00189                 EditBone *curBone, *ebone_mirr;
00190                 
00191                 for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
00192                         if (arm->layer & curBone->layer) {
00193                                 if (curBone->flag & BONE_SELECTED) {
00194                                         ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, curBone);
00195                                         if (ebone_mirr)
00196                                                 ebone_mirr->flag |= BONE_SELECTED;
00197                                 }
00198                         }
00199                 }
00200         }
00201         
00202 }
00203 
00204 static void armature_tag_select_mirrored(bArmature *arm)
00205 {
00206         EditBone *curBone;
00207 
00208         /* always untag */
00209         for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
00210                 curBone->flag &= ~BONE_DONE;
00211         }
00212 
00213         /* Select mirrored bones */
00214         if (arm->flag & ARM_MIRROR_EDIT) {
00215                 for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
00216                         if (arm->layer & curBone->layer) {
00217                                 if (curBone->flag & (BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL)) {
00218                                         EditBone *ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, curBone);
00219                                         if (ebone_mirr && (ebone_mirr->flag & BONE_SELECTED) == 0) {
00220                                                 ebone_mirr->flag |= BONE_DONE;
00221                                         }
00222                                 }
00223                         }
00224                 }
00225 
00226                 for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
00227                         if (curBone->flag & BONE_DONE) {
00228                                 EditBone *ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, curBone);
00229                                 curBone->flag |= ebone_mirr->flag & (BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL);
00230                         }
00231                 }
00232         }
00233 }
00234 
00235 
00236 /* only works when tagged */
00237 static void armature_tag_unselect(bArmature *arm)
00238 {
00239         EditBone *curBone;
00240 
00241         for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
00242                 if (curBone->flag & BONE_DONE) {
00243                         curBone->flag &= ~(BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL|BONE_DONE);
00244                 }
00245         }
00246 }
00247 
00248 /* converts Bones to EditBone list, used for tools as well */
00249 EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone *actBone)
00250 {
00251         EditBone        *eBone;
00252         EditBone        *eBoneAct= NULL;
00253         EditBone        *eBoneTest= NULL;
00254         Bone            *curBone;
00255                 
00256         for (curBone=bones->first; curBone; curBone=curBone->next) {
00257                 eBone= MEM_callocN(sizeof(EditBone), "make_editbone");
00258                 
00259                 /*      Copy relevant data from bone to eBone */
00260                 eBone->parent= parent;
00261                 BLI_strncpy(eBone->name, curBone->name, sizeof(eBone->name));
00262                 eBone->flag = curBone->flag;
00263                 
00264                 /* fix selection flags */
00265 
00266                 if (eBone->flag & BONE_SELECTED) {
00267                         /* if the bone is selected the copy its root selection to the parents tip */
00268                         eBone->flag |= BONE_TIPSEL;
00269                         if (eBone->parent && (eBone->flag & BONE_CONNECTED)) {
00270                                 eBone->parent->flag |= BONE_TIPSEL;
00271                                 eBone->flag &= ~BONE_ROOTSEL; /* this is ignored when there is a connected parent, so unset it */
00272                         }
00273                         else {
00274                                 eBone->flag |= BONE_ROOTSEL;
00275                         }
00276                 }
00277                 else {
00278                         /* if the bone is not selected, but connected to its parent
00279                          *  copy the parents tip selection state */
00280                         if(eBone->parent &&  (eBone->flag & BONE_CONNECTED)) {
00281                                 /* selecting with the mouse gives this behavior */
00282                                 if(eBone->parent->flag & BONE_TIPSEL) {
00283                                         eBone->flag |= BONE_ROOTSEL;
00284                                 }
00285                                 else {
00286                                         eBone->flag &= ~BONE_ROOTSEL;
00287                                 }
00288 
00289                                 /* probably not selected but just incase */
00290                                 eBone->flag &= ~BONE_TIPSEL;
00291                         }
00292                 }
00293 
00294                 copy_v3_v3(eBone->head, curBone->arm_head);
00295                 copy_v3_v3(eBone->tail, curBone->arm_tail);
00296                 eBone->roll = curBone->arm_roll;
00297                 
00298                 /* rest of stuff copy */
00299                 eBone->length= curBone->length;
00300                 eBone->dist= curBone->dist;
00301                 eBone->weight= curBone->weight;
00302                 eBone->xwidth= curBone->xwidth;
00303                 eBone->zwidth= curBone->zwidth;
00304                 eBone->ease1= curBone->ease1;
00305                 eBone->ease2= curBone->ease2;
00306                 eBone->rad_head= curBone->rad_head;
00307                 eBone->rad_tail= curBone->rad_tail;
00308                 eBone->segments = curBone->segments;            
00309                 eBone->layer = curBone->layer;
00310 
00311                 if(curBone->prop)
00312                         eBone->prop= IDP_CopyProperty(curBone->prop);
00313                 
00314                 BLI_addtail(edbo, eBone);
00315                 
00316                 /*      Add children if necessary */
00317                 if (curBone->childbase.first) {
00318                         eBoneTest= make_boneList(edbo, &curBone->childbase, eBone, actBone);
00319                         if(eBoneTest)
00320                                 eBoneAct= eBoneTest;
00321                 }
00322 
00323                 if(curBone==actBone)
00324                         eBoneAct= eBone;
00325         }
00326 
00327         return eBoneAct;
00328 }
00329 
00330 /* nasty stuff for converting roll in editbones into bones */
00331 /* also sets restposition in armature (arm_mat) */
00332 static void fix_bonelist_roll (ListBase *bonelist, ListBase *editbonelist)
00333 {
00334         Bone *curBone;
00335         EditBone *ebone;
00336         float premat[3][3];
00337         float postmat[3][3];
00338         float difmat[3][3];
00339         float imat[3][3];
00340         float delta[3];
00341         
00342         for (curBone=bonelist->first; curBone; curBone=curBone->next) {
00343                 /* sets local matrix and arm_mat (restpos) */
00344                 where_is_armature_bone(curBone, curBone->parent);
00345                 
00346                 /* Find the associated editbone */
00347                 for (ebone = editbonelist->first; ebone; ebone=ebone->next)
00348                         if ((Bone*)ebone->temp == curBone)
00349                                 break;
00350                 
00351                 if (ebone) {
00352                         /* Get the ebone premat */
00353                         sub_v3_v3v3(delta, ebone->tail, ebone->head);
00354                         vec_roll_to_mat3(delta, ebone->roll, premat);
00355                         
00356                         /* Get the bone postmat */
00357                         copy_m3_m4(postmat, curBone->arm_mat);
00358                         
00359                         invert_m3_m3(imat, premat);
00360                         mul_m3_m3m3(difmat, imat, postmat);
00361 #if 0
00362                         printf ("Bone %s\n", curBone->name);
00363                         print_m4("premat", premat);
00364                         print_m4("postmat", postmat);
00365                         print_m4("difmat", difmat);
00366                         printf ("Roll = %f\n",  (-atan2(difmat[2][0], difmat[2][2]) * (180.0/M_PI)));
00367 #endif
00368                         curBone->roll = (float)-atan2(difmat[2][0], difmat[2][2]);
00369                         
00370                         /* and set restposition again */
00371                         where_is_armature_bone(curBone, curBone->parent);
00372                 }
00373                 fix_bonelist_roll(&curBone->childbase, editbonelist);
00374         }
00375 }
00376 
00377 /* put EditMode back in Object */
00378 void ED_armature_from_edit(Object *obedit)
00379 {
00380         bArmature *arm= obedit->data;
00381         EditBone *eBone, *neBone;
00382         Bone    *newBone;
00383         Object *obt;
00384         
00385         /* armature bones */
00386         free_bonelist(&arm->bonebase);
00387         
00388         /* remove zero sized bones, this gives instable restposes */
00389         for (eBone=arm->edbo->first; eBone; eBone= neBone) {
00390                 float len= len_v3v3(eBone->head, eBone->tail);
00391                 neBone= eBone->next;
00392                 if (len <= 0.000001f) {         /* FLT_EPSILON is too large? */
00393                         EditBone *fBone;
00394                         
00395                         /*      Find any bones that refer to this bone  */
00396                         for (fBone=arm->edbo->first; fBone; fBone= fBone->next) {
00397                                 if (fBone->parent==eBone)
00398                                         fBone->parent= eBone->parent;
00399                         }
00400                         if (G.f & G_DEBUG)
00401                                 printf("Warning: removed zero sized bone: %s\n", eBone->name);
00402                         bone_free(arm, eBone);
00403                 }
00404         }
00405         
00406         /*      Copy the bones from the editData into the armature */
00407         for (eBone=arm->edbo->first; eBone; eBone=eBone->next) {
00408                 newBone= MEM_callocN(sizeof(Bone), "bone");
00409                 eBone->temp= newBone;   /* Associate the real Bones with the EditBones */
00410                 
00411                 BLI_strncpy(newBone->name, eBone->name, sizeof(newBone->name));
00412                 copy_v3_v3(newBone->arm_head, eBone->head);
00413                 copy_v3_v3(newBone->arm_tail, eBone->tail);
00414                 newBone->arm_roll = eBone->roll;
00415                 
00416                 newBone->flag= eBone->flag;
00417                 
00418                 if (eBone == arm->act_edbone) {
00419                         /* don't change active selection, this messes up separate which uses
00420                          * editmode toggle and can separate active bone which is de-selected originally */
00421                         /* newBone->flag |= BONE_SELECTED; */ /* important, editbones can be active with only 1 point selected */
00422                         arm->act_edbone= NULL;
00423                         arm->act_bone= newBone;
00424                 }
00425                 newBone->roll = 0.0f;
00426                 
00427                 newBone->weight = eBone->weight;
00428                 newBone->dist = eBone->dist;
00429                 
00430                 newBone->xwidth = eBone->xwidth;
00431                 newBone->zwidth = eBone->zwidth;
00432                 newBone->ease1= eBone->ease1;
00433                 newBone->ease2= eBone->ease2;
00434                 newBone->rad_head= eBone->rad_head;
00435                 newBone->rad_tail= eBone->rad_tail;
00436                 newBone->segments= eBone->segments;
00437                 newBone->layer = eBone->layer;
00438                 
00439                 if(eBone->prop)
00440                         newBone->prop= IDP_CopyProperty(eBone->prop);
00441         }
00442         
00443         /*      Fix parenting in a separate pass to ensure ebone->bone connections
00444                 are valid at this point */
00445         for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
00446                 newBone= (Bone *)eBone->temp;
00447                 if (eBone->parent) {
00448                         newBone->parent= (Bone *)eBone->parent->temp;
00449                         BLI_addtail(&newBone->parent->childbase, newBone);
00450                         
00451                         {
00452                                 float M_parentRest[3][3];
00453                                 float iM_parentRest[3][3];
00454                                 float   delta[3];
00455                                 
00456                                 /* Get the parent's  matrix (rotation only) */
00457                                 sub_v3_v3v3(delta, eBone->parent->tail, eBone->parent->head);
00458                                 vec_roll_to_mat3(delta, eBone->parent->roll, M_parentRest);
00459                                 
00460                                 /* Invert the parent matrix */
00461                                 invert_m3_m3(iM_parentRest, M_parentRest);
00462                                 
00463                                 /* Get the new head and tail */
00464                                 sub_v3_v3v3(newBone->head, eBone->head, eBone->parent->tail);
00465                                 sub_v3_v3v3(newBone->tail, eBone->tail, eBone->parent->tail);
00466                                 
00467                                 mul_m3_v3(iM_parentRest, newBone->head);
00468                                 mul_m3_v3(iM_parentRest, newBone->tail);
00469                         }
00470                 }
00471                 /*      ...otherwise add this bone to the armature's bonebase */
00472                 else {
00473                         copy_v3_v3(newBone->head, eBone->head);
00474                         copy_v3_v3(newBone->tail, eBone->tail);
00475                         BLI_addtail(&arm->bonebase, newBone);
00476                 }
00477         }
00478         
00479         /* Make a pass through the new armature to fix rolling */
00480         /* also builds restposition again (like where_is_armature) */
00481         fix_bonelist_roll(&arm->bonebase, arm->edbo);
00482         
00483         /* so all users of this armature should get rebuilt */
00484         for (obt= G.main->object.first; obt; obt= obt->id.next) {
00485                 if (obt->data==arm)
00486                         armature_rebuild_pose(obt, arm);
00487         }
00488         
00489         DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
00490 }
00491 
00492 void ED_armature_apply_transform(Object *ob, float mat[4][4])
00493 {
00494         EditBone *ebone;
00495         bArmature *arm= ob->data;
00496         float scale = mat4_to_scale(mat);       /* store the scale of the matrix here to use on envelopes */
00497         
00498         /* Put the armature into editmode */
00499         ED_armature_to_edit(ob);
00500 
00501         /* Do the rotations */
00502         for (ebone = arm->edbo->first; ebone; ebone=ebone->next){
00503                 mul_m4_v3(mat, ebone->head);
00504                 mul_m4_v3(mat, ebone->tail);
00505                 
00506                 ebone->rad_head *= scale;
00507                 ebone->rad_tail *= scale;
00508                 ebone->dist             *= scale;
00509 
00510                 /* we could be smarter and scale by the matrix along the x & z axis */
00511                 ebone->xwidth   *= scale;
00512                 ebone->zwidth   *= scale;
00513         }
00514         
00515         /* Turn the list into an armature */
00516         ED_armature_from_edit(ob);
00517         ED_armature_edit_free(ob);
00518 }
00519 
00520 /* exported for use in editors/object/ */
00521 /* 0 == do center, 1 == center new, 2 == center cursor */
00522 void docenter_armature (Scene *scene, Object *ob, float cursor[3], int centermode, int around)
00523 {
00524         Object *obedit= scene->obedit; // XXX get from context
00525         EditBone *ebone;
00526         bArmature *arm= ob->data;
00527         float cent[3];
00528 
00529         /* Put the armature into editmode */
00530         if(ob != obedit) {
00531                 ED_armature_to_edit(ob);
00532                 obedit= NULL; /* we cant use this so behave as if there is no obedit */
00533         }
00534 
00535         /* Find the centerpoint */
00536         if (centermode == 2) {
00537                 copy_v3_v3(cent, cursor);
00538                 invert_m4_m4(ob->imat, ob->obmat);
00539                 mul_m4_v3(ob->imat, cent);
00540         }
00541         else {
00542                 if(around==V3D_CENTROID) {
00543                         int total= 0;
00544                         zero_v3(cent);
00545                         for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
00546                                 total+=2;
00547                                 add_v3_v3(cent, ebone->head);
00548                                 add_v3_v3(cent, ebone->tail);
00549                         }
00550                         mul_v3_fl(cent, 1.0f/(float)total);
00551                 }
00552                 else {
00553                         float min[3], max[3];
00554                         INIT_MINMAX(min, max);
00555                         for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
00556                                 DO_MINMAX(ebone->head, min, max);
00557                                 DO_MINMAX(ebone->tail, min, max);
00558                         }
00559                         mid_v3_v3v3(cent, min, max);
00560                 }
00561         }
00562         
00563         /* Do the adjustments */
00564         for (ebone= arm->edbo->first; ebone; ebone=ebone->next) {
00565                 sub_v3_v3(ebone->head, cent);
00566                 sub_v3_v3(ebone->tail, cent);
00567         }
00568         
00569         /* Turn the list into an armature */
00570         if(obedit==NULL) {
00571                 ED_armature_from_edit(ob);
00572                 ED_armature_edit_free(ob);
00573         }
00574 
00575         /* Adjust object location for new centerpoint */
00576         if(centermode && obedit==NULL) {
00577                 mul_mat3_m4_v3(ob->obmat, cent); /* ommit translation part */
00578                 add_v3_v3(ob->loc, cent);
00579         }
00580 }
00581 
00582 /* ---------------------- */
00583 
00584 /* checks if an EditBone with a matching name already, returning the matching bone if it exists */
00585 static EditBone *editbone_name_exists (ListBase *edbo, const char *name)
00586 {
00587         return BLI_findstring(edbo, name, offsetof(EditBone, name));
00588 }
00589 
00590 /* note: there's a unique_bone_name() too! */
00591 static int editbone_unique_check(void *arg, const char *name)
00592 {
00593         struct {ListBase *lb;void *bone;} *data= arg;
00594         EditBone *dupli= editbone_name_exists(data->lb, name);
00595         return dupli && dupli != data->bone;
00596 }
00597 
00598 void unique_editbone_name (ListBase *edbo, char *name, EditBone *bone)
00599 {
00600         struct {ListBase *lb; void *bone;} data;
00601         data.lb= edbo;
00602         data.bone= bone;
00603 
00604         BLI_uniquename_cb(editbone_unique_check, &data, "Bone", '.', name, sizeof(bone->name));
00605 }
00606 
00607 /* helper for apply_armature_pose2bones - fixes parenting of objects that are bone-parented to armature */
00608 static void applyarmature_fix_boneparents (Scene *scene, Object *armob)
00609 {
00610         Object workob, *ob;
00611         
00612         /* go through all objects in database */
00613         for (ob= G.main->object.first; ob; ob= ob->id.next) {
00614                 /* if parent is bone in this armature, apply corrections */
00615                 if ((ob->parent == armob) && (ob->partype == PARBONE)) {
00616                         /* apply current transform from parent (not yet destroyed), 
00617                          * then calculate new parent inverse matrix
00618                          */
00619                         object_apply_mat4(ob, ob->obmat, FALSE, FALSE);
00620                         
00621                         what_does_parent(scene, ob, &workob);
00622                         invert_m4_m4(ob->parentinv, workob.obmat);
00623                 }
00624         }
00625 }
00626 
00627 /* set the current pose as the restpose */
00628 static int apply_armature_pose2bones_exec (bContext *C, wmOperator *op)
00629 {
00630         Scene *scene= CTX_data_scene(C);
00631         Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); // must be active object, not edit-object
00632         bArmature *arm= get_armature(ob);
00633         bPose *pose;
00634         bPoseChannel *pchan;
00635         EditBone *curbone;
00636         
00637         /* don't check if editmode (should be done by caller) */
00638         if (ob->type!=OB_ARMATURE)
00639                 return OPERATOR_CANCELLED;
00640         if (object_data_is_libdata(ob)) {
00641                 BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature."); //error_libdata();
00642                 return OPERATOR_CANCELLED;
00643         }
00644         
00645         /* helpful warnings... */
00646         // TODO: add warnings to be careful about actions, applying deforms first, etc.
00647         if (ob->adt && ob->adt->action) 
00648                 BKE_report(op->reports, RPT_WARNING, "Actions on this armature will be destroyed by this new rest pose as the transforms stored are relative to the old rest pose");
00649         
00650         /* Get editbones of active armature to alter */
00651         ED_armature_to_edit(ob);        
00652         
00653         /* get pose of active object and move it out of posemode */
00654         pose= ob->pose;
00655         
00656         for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
00657                 curbone= editbone_name_exists(arm->edbo, pchan->name);
00658                 
00659                 /* simply copy the head/tail values from pchan over to curbone */
00660                 copy_v3_v3(curbone->head, pchan->pose_head);
00661                 copy_v3_v3(curbone->tail, pchan->pose_tail);
00662                 
00663                 /* fix roll:
00664                  *      1. find auto-calculated roll value for this bone now
00665                  *      2. remove this from the 'visual' y-rotation
00666                  */
00667                 {
00668                         float premat[3][3], imat[3][3],pmat[3][3], tmat[3][3];
00669                         float delta[3], eul[3];
00670                         
00671                         /* obtain new auto y-rotation */
00672                         sub_v3_v3v3(delta, curbone->tail, curbone->head);
00673                         vec_roll_to_mat3(delta, 0.0f, premat);
00674                         invert_m3_m3(imat, premat);
00675                         
00676                         /* get pchan 'visual' matrix */
00677                         copy_m3_m4(pmat, pchan->pose_mat);
00678                         
00679                         /* remove auto from visual and get euler rotation */
00680                         mul_m3_m3m3(tmat, imat, pmat);
00681                         mat3_to_eul( eul,tmat);
00682                         
00683                         /* just use this euler-y as new roll value */
00684                         curbone->roll= eul[1];
00685                 }
00686                 
00687                 /* clear transform values for pchan */
00688                 zero_v3(pchan->loc);
00689                 zero_v3(pchan->eul);
00690                 unit_qt(pchan->quat);
00691                 unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
00692                 pchan->size[0]= pchan->size[1]= pchan->size[2]= 1.0f;
00693                 
00694                 /* set anim lock */
00695                 curbone->flag |= BONE_UNKEYED;
00696         }
00697         
00698         /* convert editbones back to bones, and then free the edit-data */
00699         ED_armature_from_edit(ob);
00700         ED_armature_edit_free(ob);
00701         
00702         /* flush positions of posebones */
00703         where_is_pose(scene, ob);
00704         
00705         /* fix parenting of objects which are bone-parented */
00706         applyarmature_fix_boneparents(scene, ob);
00707         
00708         /* note, notifier might evolve */
00709         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
00710         
00711         return OPERATOR_FINISHED;
00712 }
00713 
00714 void POSE_OT_armature_apply (wmOperatorType *ot)
00715 {
00716         /* identifiers */
00717         ot->name= "Apply Pose as Rest Pose";
00718         ot->idname= "POSE_OT_armature_apply";
00719         ot->description= "Apply the current pose as the new rest pose";
00720         
00721         /* callbacks */
00722         ot->exec= apply_armature_pose2bones_exec;
00723         ot->poll= ED_operator_posemode;
00724         
00725         /* flags */
00726         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00727 }
00728 
00729 
00730 /* set the current pose as the restpose */
00731 static int pose_visual_transform_apply_exec (bContext *C, wmOperator *UNUSED(op))
00732 {
00733         Object *ob= ED_object_pose_armature(CTX_data_active_object(C)); // must be active object, not edit-object
00734 
00735         /* don't check if editmode (should be done by caller) */
00736         if (ob->type!=OB_ARMATURE)
00737                 return OPERATOR_CANCELLED;
00738 
00739         /* loop over all selected pchans
00740          *
00741          * TODO, loop over children before parents if multiple bones
00742          * at once are to be predictable*/
00743         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones)
00744         {
00745                 float delta_mat[4][4];
00746                 
00747                 /* chan_mat already contains the delta transform from rest pose to pose-mode pose
00748                  * as that is baked into there so that B-Bones will work. Once we've set this as the
00749                  * new raw-transform components, don't recalc the poses yet, otherwise IK result will 
00750                  * change, thus changing the result we may be trying to record.
00751                  */
00752                 copy_m4_m4(delta_mat, pchan->chan_mat);
00753                 pchan_apply_mat4(pchan, delta_mat, TRUE);
00754         }
00755         CTX_DATA_END;
00756         
00757         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
00758 
00759         /* note, notifier might evolve */
00760         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
00761 
00762         return OPERATOR_FINISHED;
00763 }
00764 
00765 void POSE_OT_visual_transform_apply (wmOperatorType *ot)
00766 {
00767         /* identifiers */
00768         ot->name= "Apply Visual Transform to Pose";
00769         ot->idname= "POSE_OT_visual_transform_apply";
00770         ot->description= "Apply final constrained position of pose bones to their transform.";
00771         
00772         /* callbacks */
00773         ot->exec= pose_visual_transform_apply_exec;
00774         ot->poll= ED_operator_posemode;
00775         
00776         /* flags */
00777         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
00778 }
00779 
00780 /* ---------------------- */
00781 
00782 /* Helper function for armature joining - link fixing */
00783 static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone)
00784 {
00785         Object *ob;
00786         bPose *pose;
00787         bPoseChannel *pchant;
00788         bConstraint *con;
00789         
00790         /* let's go through all objects in database */
00791         for (ob= G.main->object.first; ob; ob= ob->id.next) {
00792                 /* do some object-type specific things */
00793                 if (ob->type == OB_ARMATURE) {
00794                         pose= ob->pose;
00795                         for (pchant= pose->chanbase.first; pchant; pchant= pchant->next) {
00796                                 for (con= pchant->constraints.first; con; con= con->next) {
00797                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
00798                                         ListBase targets = {NULL, NULL};
00799                                         bConstraintTarget *ct;
00800                                         
00801                                         /* constraint targets */
00802                                         if (cti && cti->get_constraint_targets) {
00803                                                 cti->get_constraint_targets(con, &targets);
00804                                                 
00805                                                 for (ct= targets.first; ct; ct= ct->next) {
00806                                                         if (ct->tar == srcArm) {
00807                                                                 if (ct->subtarget[0] == '\0') {
00808                                                                         ct->tar = tarArm;
00809                                                                 }
00810                                                                 else if (strcmp(ct->subtarget, pchan->name)==0) {
00811                                                                         ct->tar = tarArm;
00812                                                                         strcpy(ct->subtarget, curbone->name);
00813                                                                 }
00814                                                         }
00815                                                 }
00816                                                 
00817                                                 if (cti->flush_constraint_targets)
00818                                                         cti->flush_constraint_targets(con, &targets, 0);
00819                                         }
00820                                         
00821                                         /* action constraint? */
00822                                         if (con->type == CONSTRAINT_TYPE_ACTION) {
00823                                                 bActionConstraint *data= con->data; // XXX old animation system
00824                                                 bAction *act;
00825                                                 bActionChannel *achan;
00826                                                 
00827                                                 if (data->act) {
00828                                                         act= data->act;
00829                                                         
00830                                                         for (achan= act->chanbase.first; achan; achan= achan->next) {
00831                                                                 if (strcmp(achan->name, pchan->name)==0)
00832                                                                         BLI_strncpy(achan->name, curbone->name, sizeof(achan->name));
00833                                                         }
00834                                                 }
00835                                         }
00836                                         
00837                                 }
00838                         }
00839                 }
00840                         
00841                 /* fix object-level constraints */
00842                 if (ob != srcArm) {
00843                         for (con= ob->constraints.first; con; con= con->next) {
00844                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
00845                                 ListBase targets = {NULL, NULL};
00846                                 bConstraintTarget *ct;
00847                                 
00848                                 /* constraint targets */
00849                                 if (cti && cti->get_constraint_targets) {
00850                                         cti->get_constraint_targets(con, &targets);
00851                                         
00852                                         for (ct= targets.first; ct; ct= ct->next) {
00853                                                 if (ct->tar == srcArm) {
00854                                                         if (ct->subtarget[0] == '\0') {
00855                                                                 ct->tar = tarArm;
00856                                                         }
00857                                                         else if (strcmp(ct->subtarget, pchan->name)==0) {
00858                                                                 ct->tar = tarArm;
00859                                                                 strcpy(ct->subtarget, curbone->name);
00860                                                         }
00861                                                 }
00862                                         }
00863                                         
00864                                         if (cti->flush_constraint_targets)
00865                                                 cti->flush_constraint_targets(con, &targets, 0);
00866                                 }
00867                         }
00868                 }
00869                 
00870                 /* See if an object is parented to this armature */
00871                 if (ob->parent && (ob->parent == srcArm)) {
00872                         /* Is object parented to a bone of this src armature? */
00873                         if (ob->partype==PARBONE) {
00874                                 /* bone name in object */
00875                                 if (!strcmp(ob->parsubstr, pchan->name))
00876                                         BLI_strncpy(ob->parsubstr, curbone->name, sizeof(ob->parsubstr));
00877                         }
00878                         
00879                         /* make tar armature be new parent */
00880                         ob->parent = tarArm;
00881                 }
00882         }       
00883 }
00884 
00885 /* join armature exec is exported for use in object->join objects operator... */
00886 int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
00887 {
00888         Main *bmain= CTX_data_main(C);
00889         Scene *scene= CTX_data_scene(C);
00890         Object  *ob= CTX_data_active_object(C);
00891         bArmature *arm= (ob)? ob->data: NULL;
00892         bPose *pose, *opose;
00893         bPoseChannel *pchan, *pchann;
00894         EditBone *curbone;
00895         float   mat[4][4], oimat[4][4];
00896         
00897         /*      Ensure we're not in editmode and that the active object is an armature*/
00898         if (!ob || ob->type!=OB_ARMATURE)
00899                 return OPERATOR_CANCELLED;
00900         if (!arm || arm->edbo)
00901                 return OPERATOR_CANCELLED;
00902         
00903         /* Get editbones of active armature to add editbones to */
00904         ED_armature_to_edit(ob);
00905         
00906         /* get pose of active object and move it out of posemode */
00907         pose= ob->pose;
00908         ob->mode &= ~OB_MODE_POSE;
00909 
00910         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
00911                 if ((base->object->type==OB_ARMATURE) && (base->object!=ob)) {
00912                         bArmature *curarm= base->object->data;
00913                         
00914                         /* Make a list of editbones in current armature */
00915                         ED_armature_to_edit(base->object);
00916                         
00917                         /* Get Pose of current armature */
00918                         opose= base->object->pose;
00919                         base->object->mode &= ~OB_MODE_POSE;
00920                         //BASACT->flag &= ~OB_MODE_POSE;
00921                         
00922                         /* Find the difference matrix */
00923                         invert_m4_m4(oimat, ob->obmat);
00924                         mul_m4_m4m4(mat, base->object->obmat, oimat);
00925                         
00926                         /* Copy bones and posechannels from the object to the edit armature */
00927                         for (pchan=opose->chanbase.first; pchan; pchan=pchann) {
00928                                 pchann= pchan->next;
00929                                 curbone= editbone_name_exists(curarm->edbo, pchan->name);
00930                                 
00931                                 /* Get new name */
00932                                 unique_editbone_name(arm->edbo, curbone->name, NULL);
00933                                 
00934                                 /* Transform the bone */
00935                                 {
00936                                         float premat[4][4];
00937                                         float postmat[4][4];
00938                                         float difmat[4][4];
00939                                         float imat[4][4];
00940                                         float temp[3][3];
00941                                         float delta[3];
00942                                         
00943                                         /* Get the premat */
00944                                         sub_v3_v3v3(delta, curbone->tail, curbone->head);
00945                                         vec_roll_to_mat3(delta, curbone->roll, temp);
00946                                         
00947                                         unit_m4(premat); /* Mat4MulMat34 only sets 3x3 part */
00948                                         mul_m4_m3m4(premat, temp, mat);
00949                                         
00950                                         mul_m4_v3(mat, curbone->head);
00951                                         mul_m4_v3(mat, curbone->tail);
00952                                         
00953                                         /* Get the postmat */
00954                                         sub_v3_v3v3(delta, curbone->tail, curbone->head);
00955                                         vec_roll_to_mat3(delta, curbone->roll, temp);
00956                                         copy_m4_m3(postmat, temp);
00957                                         
00958                                         /* Find the roll */
00959                                         invert_m4_m4(imat, premat);
00960                                         mul_m4_m4m4(difmat, postmat, imat);
00961                                         
00962                                         curbone->roll -= (float)atan2(difmat[2][0], difmat[2][2]);
00963                                 }
00964                                 
00965                                 /* Fix Constraints and Other Links to this Bone and Armature */
00966                                 joined_armature_fix_links(ob, base->object, pchan, curbone);
00967                                 
00968                                 /* Rename pchan */
00969                                 BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
00970                                 
00971                                 /* Jump Ship! */
00972                                 BLI_remlink(curarm->edbo, curbone);
00973                                 BLI_addtail(arm->edbo, curbone);
00974                                 
00975                                 BLI_remlink(&opose->chanbase, pchan);
00976                                 BLI_addtail(&pose->chanbase, pchan);
00977                                 free_pose_channels_hash(opose);
00978                                 free_pose_channels_hash(pose);
00979                         }
00980                         
00981                         ED_base_object_free_and_unlink(bmain, scene, base);
00982                 }
00983         }
00984         CTX_DATA_END;
00985         
00986         DAG_scene_sort(bmain, scene);   // because we removed object(s)
00987 
00988         ED_armature_from_edit(ob);
00989         ED_armature_edit_free(ob);
00990 
00991         WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene);
00992         
00993         return OPERATOR_FINISHED;
00994 }
00995 
00996 /* ---------------------- */
00997 
00998 /* Helper function for armature separating - link fixing */
00999 static void separated_armature_fix_links(Object *origArm, Object *newArm)
01000 {
01001         Object *ob;
01002         bPoseChannel *pchan;
01003         bConstraint *con;
01004         ListBase *opchans, *npchans;
01005         
01006         /* get reference to list of bones in original and new armatures  */
01007         opchans= &origArm->pose->chanbase;
01008         npchans= &newArm->pose->chanbase;
01009         
01010         /* let's go through all objects in database */
01011         for (ob= G.main->object.first; ob; ob= ob->id.next) {
01012                 /* do some object-type specific things */
01013                 if (ob->type == OB_ARMATURE) {
01014                         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
01015                                 for (con= pchan->constraints.first; con; con= con->next) {
01016                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
01017                                         ListBase targets = {NULL, NULL};
01018                                         bConstraintTarget *ct;
01019                                         
01020                                         /* constraint targets */
01021                                         if (cti && cti->get_constraint_targets) {
01022                                                 cti->get_constraint_targets(con, &targets);
01023                                                 
01024                                                 for (ct= targets.first; ct; ct= ct->next) {
01025                                                         /* any targets which point to original armature are redirected to the new one only if:
01026                                                          *      - the target isn't origArm/newArm itself
01027                                                          *      - the target is one that can be found in newArm/origArm
01028                                                          */
01029                                                         if (ct->subtarget[0] != 0) {
01030                                                                 if (ct->tar == origArm) {
01031                                                                         if(BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) {
01032                                                                                 ct->tar= newArm;
01033                                                                         }
01034                                                                 }
01035                                                                 else if (ct->tar == newArm) {
01036                                                                         if(BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) {
01037                                                                                 ct->tar= origArm;
01038                                                                         }
01039                                                                 }
01040                                                         }
01041                                                 }
01042 
01043                                                 if (cti->flush_constraint_targets) {
01044                                                         cti->flush_constraint_targets(con, &targets, 0);
01045                                                 }
01046                                         }
01047                                 }
01048                         }
01049                 }
01050                         
01051                 /* fix object-level constraints */
01052                 if (ob != origArm) {
01053                         for (con= ob->constraints.first; con; con= con->next) {
01054                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
01055                                 ListBase targets = {NULL, NULL};
01056                                 bConstraintTarget *ct;
01057                                 
01058                                 /* constraint targets */
01059                                 if (cti && cti->get_constraint_targets) {
01060                                         cti->get_constraint_targets(con, &targets);
01061                                         
01062                                         for (ct= targets.first; ct; ct= ct->next) {
01063                                                 /* any targets which point to original armature are redirected to the new one only if:
01064                                                  *      - the target isn't origArm/newArm itself
01065                                                  *      - the target is one that can be found in newArm/origArm
01066                                                  */
01067                                                 if(ct->subtarget[0] != '\0')  {
01068                                                         if (ct->tar == origArm) {
01069                                                                 if(BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) {
01070                                                                         ct->tar= newArm;
01071                                                                 }
01072                                                         }
01073                                                         else if (ct->tar == newArm) {
01074                                                                 if(BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) {
01075                                                                         ct->tar= origArm;
01076                                                                 }
01077                                                         }
01078                                                 }
01079                                         }
01080 
01081                                         if (cti->flush_constraint_targets) {
01082                                                 cti->flush_constraint_targets(con, &targets, 0);
01083                                         }
01084                                 }
01085                         }
01086                 }
01087                 
01088                 /* See if an object is parented to this armature */
01089                 if (ob->parent && (ob->parent == origArm)) {
01090                         /* Is object parented to a bone of this src armature? */
01091                         if ((ob->partype == PARBONE) && (ob->parsubstr[0] != '\0')) {
01092                                 if(BLI_findstring(npchans, ob->parsubstr, offsetof(bPoseChannel, name))) {
01093                                         ob->parent= newArm;
01094                                 }
01095                         }
01096                 }
01097         }       
01098 }
01099 
01100 /* Helper function for armature separating - remove certain bones from the given armature 
01101  *      sel: remove selected bones from the armature, otherwise the unselected bones are removed
01102  *  (ob is not in editmode)
01103  */
01104 static void separate_armature_bones(Object *ob, short sel) 
01105 {
01106         bArmature *arm= (bArmature *)ob->data;
01107         bPoseChannel *pchan, *pchann;
01108         EditBone *curbone;
01109         
01110         /* make local set of editbones to manipulate here */
01111         ED_armature_to_edit(ob);
01112         
01113         /* go through pose-channels, checking if a bone should be removed */
01114         for (pchan=ob->pose->chanbase.first; pchan; pchan=pchann) {
01115                 pchann= pchan->next;
01116                 curbone= editbone_name_exists(arm->edbo, pchan->name);
01117                 
01118                 /* check if bone needs to be removed */
01119                 if ( (sel && (curbone->flag & BONE_SELECTED)) ||
01120                          (!sel && !(curbone->flag & BONE_SELECTED)) )
01121                 {
01122                         EditBone *ebo;
01123                         bPoseChannel *pchn;
01124                         
01125                         /* clear the bone->parent var of any bone that had this as its parent  */
01126                         for (ebo= arm->edbo->first; ebo; ebo= ebo->next) {
01127                                 if (ebo->parent == curbone) {
01128                                         ebo->parent= NULL;
01129                                         ebo->temp= NULL; /* this is needed to prevent random crashes with in ED_armature_from_edit */
01130                                         ebo->flag &= ~BONE_CONNECTED;
01131                                 }
01132                         }
01133                         
01134                         /* clear the pchan->parent var of any pchan that had this as its parent */
01135                         for (pchn= ob->pose->chanbase.first; pchn; pchn=pchn->next) {
01136                                 if (pchn->parent == pchan)
01137                                         pchn->parent= NULL;
01138                         }
01139                         
01140                         /* free any of the extra-data this pchan might have */
01141                         free_pose_channel(pchan);
01142                         free_pose_channels_hash(ob->pose);
01143                         
01144                         /* get rid of unneeded bone */
01145                         bone_free(arm, curbone);
01146                         BLI_freelinkN(&ob->pose->chanbase, pchan);
01147                 }
01148         }
01149         
01150         /* exit editmode (recalculates pchans too) */
01151         ED_armature_from_edit(ob);
01152         ED_armature_edit_free(ob);
01153 }
01154 
01155 /* separate selected bones into their armature */
01156 static int separate_armature_exec (bContext *C, wmOperator *UNUSED(op))
01157 {
01158         Main *bmain= CTX_data_main(C);
01159         Scene *scene= CTX_data_scene(C);
01160         Object *obedit= CTX_data_edit_object(C);
01161         Object *oldob, *newob;
01162         Base *oldbase, *newbase;
01163         
01164         /* sanity checks */
01165         if (obedit == NULL)
01166                 return OPERATOR_CANCELLED;
01167         
01168         /* set wait cursor in case this takes a while */
01169         WM_cursor_wait(1);
01170         
01171         /* we are going to do this as follows (unlike every other instance of separate):
01172          *      1. exit editmode +posemode for active armature/base. Take note of what this is.
01173          *      2. duplicate base - BASACT is the new one now
01174          *      3. for each of the two armatures, enter editmode -> remove appropriate bones -> exit editmode + recalc
01175          *      4. fix constraint links
01176          *      5. make original armature active and enter editmode
01177          */
01178         
01179         /* 1) only edit-base selected */
01180         // TODO: use context iterators for this?
01181         CTX_DATA_BEGIN(C, Base *, base, visible_bases) {
01182                 if (base->object==obedit) base->flag |= 1;
01183                 else base->flag &= ~1;
01184         }
01185         CTX_DATA_END;
01186         
01187         /* 1) store starting settings and exit editmode */
01188         oldob= obedit;
01189         oldbase= BASACT;
01190         oldob->mode &= ~OB_MODE_POSE;
01191         //oldbase->flag &= ~OB_POSEMODE;
01192         
01193         ED_armature_from_edit(obedit);
01194         ED_armature_edit_free(obedit);
01195         
01196         /* 2) duplicate base */
01197         newbase= ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
01198         newob= newbase->object;         
01199         newbase->flag &= ~SELECT;
01200         
01201         
01202         /* 3) remove bones that shouldn't still be around on both armatures */
01203         separate_armature_bones(oldob, 1);
01204         separate_armature_bones(newob, 0);
01205         
01206         
01207         /* 4) fix links before depsgraph flushes */ // err... or after?
01208         separated_armature_fix_links(oldob, newob);
01209         
01210         DAG_id_tag_update(&oldob->id, OB_RECALC_DATA);  /* this is the original one */
01211         DAG_id_tag_update(&newob->id, OB_RECALC_DATA);  /* this is the separated one */
01212         
01213         
01214         /* 5) restore original conditions */
01215         obedit= oldob;
01216         
01217         ED_armature_to_edit(obedit);
01218         
01219         /* note, notifier might evolve */
01220         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, obedit);
01221         
01222         /* recalc/redraw + cleanup */
01223         WM_cursor_wait(0);
01224         
01225         return OPERATOR_FINISHED;
01226 }
01227 
01228 void ARMATURE_OT_separate (wmOperatorType *ot)
01229 {
01230         /* identifiers */
01231         ot->name= "Separate Bones";
01232         ot->idname= "ARMATURE_OT_separate";
01233         ot->description= "Isolate selected bones into a separate armature";
01234         
01235         /* callbacks */
01236         ot->invoke= WM_operator_confirm;
01237         ot->exec= separate_armature_exec;
01238         ot->poll= ED_operator_editarmature;
01239         
01240         /* flags */
01241         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01242 }
01243 
01244 /* **************** END tools on Editmode Armature **************** */
01245 /* **************** PoseMode & EditMode *************************** */
01246 
01247 /* only for opengl selection indices */
01248 Bone *get_indexed_bone (Object *ob, int index)
01249 {
01250         bPoseChannel *pchan;
01251         if(ob->pose==NULL) return NULL;
01252         index>>=16;             // bone selection codes use left 2 bytes
01253         
01254         pchan= BLI_findlink(&ob->pose->chanbase, index);
01255         return pchan ? pchan->bone : NULL;
01256 }
01257 
01258 /* See if there are any selected bones in this buffer */
01259 /* only bones from base are checked on */
01260 static void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short findunsel)
01261 {
01262         Object *obedit= scene->obedit; // XXX get from context
01263         Bone *bone;
01264         EditBone *ebone;
01265         void *firstunSel=NULL, *firstSel=NULL, *data;
01266         unsigned int hitresult;
01267         short i, takeNext=0, sel;
01268         
01269         for (i=0; i< hits; i++){
01270                 hitresult = buffer[3+(i*4)];
01271                 
01272                 if (!(hitresult & BONESEL_NOSEL)) {     // -1
01273                         if(hitresult & BONESEL_ANY) {   // to avoid including objects in selection
01274                                 
01275                                 hitresult &= ~(BONESEL_ANY);
01276                                 /* Determine what the current bone is */
01277                                 if (obedit==NULL || base->object!=obedit) {
01278                                         /* no singular posemode, so check for correct object */
01279                                         if(base->selcol == (hitresult & 0xFFFF)) {
01280                                                 bone = get_indexed_bone(base->object, hitresult);
01281                                                 
01282                                                 if (findunsel)
01283                                                         sel = (bone->flag & BONE_SELECTED);
01284                                                 else
01285                                                         sel = !(bone->flag & BONE_SELECTED);
01286                                                 
01287                                                 data = bone;
01288                                         }
01289                                         else {
01290                                                 data= NULL;
01291                                                 sel= 0;
01292                                         }
01293                                 }
01294                                 else{
01295                                         bArmature *arm= obedit->data;
01296                                         
01297                                         ebone = BLI_findlink(arm->edbo, hitresult);
01298                                         if (findunsel)
01299                                                 sel = (ebone->flag & BONE_SELECTED);
01300                                         else
01301                                                 sel = !(ebone->flag & BONE_SELECTED);
01302                                         
01303                                         data = ebone;
01304                                 }
01305                                 
01306                                 if(data) {
01307                                         if (sel) {
01308                                                 if(!firstSel) firstSel= data;
01309                                                 takeNext=1;
01310                                         }
01311                                         else {
01312                                                 if (!firstunSel)
01313                                                         firstunSel=data;
01314                                                 if (takeNext)
01315                                                         return data;
01316                                         }
01317                                 }
01318                         }
01319                 }
01320         }
01321         
01322         if (firstunSel)
01323                 return firstunSel;
01324         else 
01325                 return firstSel;
01326 }
01327 
01328 
01329 
01330 /* used by posemode as well editmode */
01331 /* only checks scene->basact! */
01332 /* x and y are mouse coords (area space) */
01333 static void *get_nearest_bone (bContext *C, short findunsel, int x, int y)
01334 {
01335         ViewContext vc;
01336         rcti rect;
01337         unsigned int buffer[MAXPICKBUF];
01338         short hits;
01339         
01340         view3d_set_viewcontext(C, &vc);
01341         
01342         // rect.xmin= ... mouseco!
01343         rect.xmin= rect.xmax= x;
01344         rect.ymin= rect.ymax= y;
01345         
01346         glInitNames();
01347         hits= view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect);
01348 
01349         if (hits>0)
01350                 return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel);
01351         
01352         return NULL;
01353 }
01354 
01355 /* Get the first available child of an editbone */
01356 static EditBone *editbone_get_child(bArmature *arm, EditBone *pabone, short use_visibility)
01357 {
01358         EditBone *curbone, *chbone=NULL;
01359         
01360         for (curbone= arm->edbo->first; curbone; curbone= curbone->next) {
01361                 if (curbone->parent == pabone) {
01362                         if (use_visibility) {
01363                                 if ((arm->layer & curbone->layer) && !(pabone->flag & BONE_HIDDEN_A)) {
01364                                         chbone = curbone;
01365                                 }
01366                         }
01367                         else
01368                                 chbone = curbone;
01369                 }
01370         }
01371         
01372         return chbone;
01373 }
01374 
01375 /* **************** END PoseMode & EditMode *************************** */
01376 /* **************** Posemode stuff ********************** */
01377 
01378 
01379 static void selectconnected_posebonechildren (Object *ob, Bone *bone, int extend)
01380 {
01381         Bone *curBone;
01382         
01383         /* stop when unconnected child is encontered, or when unselectable bone is encountered */
01384         if (!(bone->flag & BONE_CONNECTED) || (bone->flag & BONE_UNSELECTABLE))
01385                 return;
01386         
01387                 // XXX old cruft! use notifiers instead
01388         //select_actionchannel_by_name (ob->action, bone->name, !(shift));
01389         
01390         if (extend)
01391                 bone->flag &= ~BONE_SELECTED;
01392         else
01393                 bone->flag |= BONE_SELECTED;
01394         
01395         for (curBone=bone->childbase.first; curBone; curBone=curBone->next)
01396                 selectconnected_posebonechildren(ob, curBone, extend);
01397 }
01398 
01399 /* within active object context */
01400 /* previously known as "selectconnected_posearmature" */
01401 static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event)
01402 {
01403         Object *ob= CTX_data_edit_object(C);
01404         Bone *bone, *curBone, *next= NULL;
01405         int extend= RNA_boolean_get(op->ptr, "extend");
01406 
01407         view3d_operator_needs_opengl(C);
01408         
01409         if (extend)
01410                 bone= get_nearest_bone(C, 0, event->mval[0], event->mval[1]);
01411         else
01412                 bone= get_nearest_bone(C, 1, event->mval[0], event->mval[1]);
01413         
01414         if (!bone)
01415                 return OPERATOR_CANCELLED;
01416         
01417         /* Select parents */
01418         for (curBone=bone; curBone; curBone=next){
01419                 /* ignore bone if cannot be selected */
01420                 if ((curBone->flag & BONE_UNSELECTABLE) == 0) { 
01421                                 // XXX old cruft! use notifiers instead
01422                         //select_actionchannel_by_name (ob->action, curBone->name, !(shift));
01423                         
01424                         if (extend)
01425                                 curBone->flag &= ~BONE_SELECTED;
01426                         else
01427                                 curBone->flag |= BONE_SELECTED;
01428                         
01429                         if (curBone->flag & BONE_CONNECTED)
01430                                 next=curBone->parent;
01431                         else
01432                                 next=NULL;
01433                 }
01434                 else
01435                         next= NULL;
01436         }
01437         
01438         /* Select children */
01439         for (curBone=bone->childbase.first; curBone; curBone=next)
01440                 selectconnected_posebonechildren(ob, curBone, extend);
01441         
01442         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
01443 
01444         return OPERATOR_FINISHED;
01445 }
01446 
01447 static int pose_select_linked_poll(bContext *C)
01448 {
01449         return ( ED_operator_view3d_active(C) && ED_operator_posemode(C) );
01450 }
01451 
01452 void POSE_OT_select_linked(wmOperatorType *ot)
01453 {
01454         /* identifiers */
01455         ot->name= "Select Connected";
01456         ot->idname= "POSE_OT_select_linked";
01457         ot->description= "Select bones related to selected ones by parent/child relationships";
01458         
01459         /* api callbacks */
01460         ot->exec= NULL;
01461         ot->invoke= pose_select_connected_invoke;
01462         ot->poll= pose_select_linked_poll;
01463         
01464         /* flags */
01465         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01466         
01467         /* props */     
01468         RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
01469 }
01470 
01471 /* **************** END Posemode stuff ********************** */
01472 /* **************** EditMode stuff ********************** */
01473 
01474 /* called in space.c */
01475 /* previously "selectconnected_armature" */
01476 static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
01477 {
01478         bArmature *arm;
01479         EditBone *bone, *curBone, *next;
01480         int extend= RNA_boolean_get(op->ptr, "extend");
01481         Object *obedit= CTX_data_edit_object(C);
01482         arm= obedit->data;
01483 
01484         view3d_operator_needs_opengl(C);
01485 
01486         if (extend)
01487                 bone= get_nearest_bone(C, 0, event->mval[0], event->mval[1]);
01488         else
01489                 bone= get_nearest_bone(C, 1, event->mval[0], event->mval[1]);
01490 
01491         if (!bone)
01492                 return OPERATOR_CANCELLED;
01493 
01494         /* Select parents */
01495         for (curBone=bone; curBone; curBone=next) {
01496                 if ((curBone->flag & BONE_UNSELECTABLE) == 0) {
01497                         if (extend) {
01498                                 curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
01499                         }
01500                         else{
01501                                 curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
01502                         }
01503                 }
01504                 
01505                 if (curBone->flag & BONE_CONNECTED)
01506                         next=curBone->parent;
01507                 else
01508                         next=NULL;
01509         }
01510 
01511         /* Select children */
01512         while (bone) {
01513                 for (curBone=arm->edbo->first; curBone; curBone=next) {
01514                         next = curBone->next;
01515                         if ((curBone->parent == bone) && (curBone->flag & BONE_UNSELECTABLE)==0) {
01516                                 if (curBone->flag & BONE_CONNECTED) {
01517                                         if (extend)
01518                                                 curBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
01519                                         else
01520                                                 curBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
01521                                         bone=curBone;
01522                                         break;
01523                                 }
01524                                 else { 
01525                                         bone=NULL;
01526                                         break;
01527                                 }
01528                         }
01529                 }
01530                 if (!curBone)
01531                         bone=NULL;
01532         }
01533         
01534         ED_armature_sync_selection(arm->edbo);
01535         
01536         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
01537         
01538         return OPERATOR_FINISHED;
01539 }
01540 
01541 static int armature_select_linked_poll(bContext *C)
01542 {
01543         return ( ED_operator_view3d_active(C) && ED_operator_editarmature(C) );
01544 }
01545 
01546 void ARMATURE_OT_select_linked(wmOperatorType *ot)
01547 {
01548         /* identifiers */
01549         ot->name= "Select Connected";
01550         ot->idname= "ARMATURE_OT_select_linked";
01551         ot->description= "Select bones related to selected ones by parent/child relationships";
01552         
01553         /* api callbacks */
01554         ot->exec= NULL;
01555         ot->invoke= armature_select_linked_invoke;
01556         ot->poll= armature_select_linked_poll;
01557         
01558         /* flags */
01559         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01560         
01561         /* properties s*/
01562         RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first.");
01563 }
01564 
01565 /* does bones and points */
01566 /* note that BONE ROOT only gets drawn for root bones (or without IK) */
01567 static EditBone *get_nearest_editbonepoint (ViewContext *vc, const int mval[2], ListBase *edbo, int findunsel, int *selmask)
01568 {
01569         EditBone *ebone;
01570         rcti rect;
01571         unsigned int buffer[MAXPICKBUF];
01572         unsigned int hitresult, besthitresult=BONESEL_NOSEL;
01573         int i, mindep= 4;
01574         short hits;
01575 
01576         glInitNames();
01577         
01578         rect.xmin= mval[0]-5;
01579         rect.xmax= mval[0]+5;
01580         rect.ymin= mval[1]-5;
01581         rect.ymax= mval[1]+5;
01582         
01583         hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
01584         if(hits==0) {
01585                 rect.xmin= mval[0]-12;
01586                 rect.xmax= mval[0]+12;
01587                 rect.ymin= mval[1]-12;
01588                 rect.ymax= mval[1]+12;
01589                 hits= view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect);
01590         }
01591         /* See if there are any selected bones in this group */
01592         if (hits>0) {
01593                 
01594                 if(hits==1) {
01595                         if (!(buffer[3] & BONESEL_NOSEL)) 
01596                                 besthitresult= buffer[3];
01597                 }
01598                 else {
01599                         for (i=0; i< hits; i++) {
01600                                 hitresult= buffer[3+(i*4)];
01601                                 if (!(hitresult & BONESEL_NOSEL)) {
01602                                         int dep;
01603                                         
01604                                         ebone = BLI_findlink(edbo, hitresult & ~BONESEL_ANY);
01605                                         
01606                                         /* clicks on bone points get advantage */
01607                                         if( hitresult & (BONESEL_ROOT|BONESEL_TIP)) {
01608                                                 /* but also the unselected one */
01609                                                 if(findunsel) {
01610                                                         if( (hitresult & BONESEL_ROOT) && (ebone->flag & BONE_ROOTSEL)==0) 
01611                                                                 dep= 1;
01612                                                         else if( (hitresult & BONESEL_TIP) && (ebone->flag & BONE_TIPSEL)==0) 
01613                                                                 dep= 1;
01614                                                         else 
01615                                                                 dep= 2;
01616                                                 }
01617                                                 else dep= 2;
01618                                         }
01619                                         else {
01620                                                 /* bone found */
01621                                                 if(findunsel) {
01622                                                         if((ebone->flag & BONE_SELECTED)==0)
01623                                                                 dep= 2;
01624                                                         else
01625                                                                 dep= 3;
01626                                                 }
01627                                                 else dep= 3;
01628                                         }
01629                                         if(dep < mindep) {
01630                                                 mindep= dep;
01631                                                 besthitresult= hitresult;
01632                                         }
01633                                 }
01634                         }
01635                 }
01636                 
01637                 if (!(besthitresult & BONESEL_NOSEL)) {
01638                         
01639                         ebone= BLI_findlink(edbo, besthitresult & ~BONESEL_ANY);
01640                         
01641                         *selmask = 0;
01642                         if (besthitresult & BONESEL_ROOT)
01643                                 *selmask |= BONE_ROOTSEL;
01644                         if (besthitresult & BONESEL_TIP)
01645                                 *selmask |= BONE_TIPSEL;
01646                         if (besthitresult & BONESEL_BONE)
01647                                 *selmask |= BONE_SELECTED;
01648                         return ebone;
01649                 }
01650         }
01651         *selmask = 0;
01652         return NULL;
01653 }
01654 
01655 /* previously delete_armature */
01656 /* only editmode! */
01657 static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
01658 {
01659         bArmature *arm;
01660         EditBone        *curBone, *ebone_next;
01661         bConstraint *con;
01662         Object *obedit= CTX_data_edit_object(C); // XXX get from context
01663         arm = obedit->data;
01664 
01665         /* cancel if nothing selected */
01666         if (CTX_DATA_COUNT(C, selected_bones) == 0)
01667                 return OPERATOR_CANCELLED;
01668         
01669         armature_select_mirrored(arm);
01670         
01671         /*  First erase any associated pose channel */
01672         if (obedit->pose) {
01673                 bPoseChannel *pchan, *pchan_next;
01674                 for (pchan=obedit->pose->chanbase.first; pchan; pchan= pchan_next) {
01675                         pchan_next= pchan->next;
01676                         curBone = editbone_name_exists(arm->edbo, pchan->name);
01677                         
01678                         if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
01679                                 free_pose_channel(pchan);
01680                                 free_pose_channels_hash(obedit->pose);
01681                                 BLI_freelinkN (&obedit->pose->chanbase, pchan);
01682                         }
01683                         else {
01684                                 for (con= pchan->constraints.first; con; con= con->next) {
01685                                         bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
01686                                         ListBase targets = {NULL, NULL};
01687                                         bConstraintTarget *ct;
01688                                         
01689                                         if (cti && cti->get_constraint_targets) {
01690                                                 cti->get_constraint_targets(con, &targets);
01691                                                 
01692                                                 for (ct= targets.first; ct; ct= ct->next) {
01693                                                         if (ct->tar == obedit) {
01694                                                                 if (ct->subtarget[0]) {
01695                                                                         curBone = editbone_name_exists(arm->edbo, ct->subtarget);
01696                                                                         if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
01697                                                                                 con->flag |= CONSTRAINT_DISABLE;
01698                                                                                 ct->subtarget[0]= 0;
01699                                                                         }
01700                                                                 }
01701                                                         }
01702                                                 }
01703                                                 
01704                                                 if (cti->flush_constraint_targets)
01705                                                         cti->flush_constraint_targets(con, &targets, 0);
01706                                         }
01707                                 }
01708                         }
01709                 }
01710         }
01711         
01712         
01713         for (curBone=arm->edbo->first; curBone; curBone= ebone_next) {
01714                 ebone_next= curBone->next;
01715                 if (arm->layer & curBone->layer) {
01716                         if (curBone->flag & BONE_SELECTED) {
01717                                 if(curBone==arm->act_edbone) arm->act_edbone= NULL;
01718                                 ED_armature_edit_bone_remove(arm, curBone);
01719                         }
01720                 }
01721         }
01722         
01723         
01724         ED_armature_sync_selection(arm->edbo);
01725 
01726         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
01727 
01728         return OPERATOR_FINISHED;
01729 }
01730 
01731 void ARMATURE_OT_delete(wmOperatorType *ot)
01732 {
01733         /* identifiers */
01734         ot->name= "Delete Selected Bone(s)";
01735         ot->idname= "ARMATURE_OT_delete";
01736         ot->description= "Remove selected bones from the armature";
01737         
01738         /* api callbacks */
01739         ot->invoke = WM_operator_confirm;
01740         ot->exec = armature_delete_selected_exec;
01741         ot->poll = ED_operator_editarmature;
01742         
01743         /* flags */
01744         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
01745 }
01746 
01747 /* toggle==0: deselect
01748  * toggle==1: swap (based on test)
01749  * toggle==2: swap (no test), CURRENTLY UNUSED
01750  */
01751 void ED_armature_deselect_all(Object *obedit, int toggle)
01752 {
01753         bArmature *arm= obedit->data;
01754         EditBone        *eBone;
01755         int                     sel=1;
01756         
01757         if(toggle==1) {
01758                 /*      Determine if there are any selected bones
01759                 And therefore whether we are selecting or deselecting */
01760                 for (eBone=arm->edbo->first;eBone;eBone=eBone->next){
01761                         //                      if(arm->layer & eBone->layer) {
01762                         if (eBone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)){
01763                                 sel=0;
01764                                 break;
01765                         }
01766                         //                      }
01767                 }
01768         }
01769         else sel= toggle;
01770         
01771         /*      Set the flags */
01772         for (eBone=arm->edbo->first;eBone;eBone=eBone->next) {
01773                 if (sel==2) {
01774                         /* invert selection of bone */
01775                         if(EBONE_VISIBLE(arm, eBone)) {
01776                                 eBone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
01777                                 if(arm->act_edbone==eBone)
01778                                         arm->act_edbone= NULL;
01779                         }
01780                 }
01781                 else if (sel==1) {
01782                         /* select bone */
01783                         if(EBONE_VISIBLE(arm, eBone)) {
01784                                 eBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
01785                                 if(eBone->parent)
01786                                         eBone->parent->flag |= (BONE_TIPSEL);
01787                         }
01788                 }
01789                 else {
01790                         /* deselect bone */
01791                         eBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
01792                         if(arm->act_edbone==eBone)
01793                                 arm->act_edbone= NULL;
01794                 }
01795         }
01796         
01797         ED_armature_sync_selection(arm->edbo);
01798 }
01799 
01800 void ED_armature_deselect_all_visible(Object *obedit)
01801 {
01802         bArmature *arm= obedit->data;
01803         EditBone        *ebone;
01804 
01805         for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
01806                 /* first and foremost, bone must be visible and selected */
01807                 if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_UNSELECTABLE)==0) {
01808                         ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
01809                 }
01810         }
01811 
01812         ED_armature_sync_selection(arm->edbo);
01813 }
01814 
01815 /* accounts for connected parents */
01816 static int ebone_select_flag(EditBone *ebone)
01817 {
01818         if(ebone->parent && (ebone->flag & BONE_CONNECTED)) {
01819                 return ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0) | (ebone->flag & (BONE_SELECTED|BONE_TIPSEL));
01820         }
01821         else {
01822                 return ebone->flag & (BONE_SELECTED|BONE_ROOTSEL|BONE_TIPSEL);
01823         }
01824 }
01825 
01826 /* context: editmode armature in view3d */
01827 int mouse_armature(bContext *C, const int mval[2], int extend)
01828 {
01829         Object *obedit= CTX_data_edit_object(C);
01830         bArmature *arm= obedit->data;
01831         ViewContext vc;
01832         EditBone *nearBone = NULL;
01833         int     selmask;
01834 
01835         view3d_set_viewcontext(C, &vc);
01836         
01837         BIF_sk_selectStroke(C, mval, extend);
01838         
01839         nearBone= get_nearest_editbonepoint(&vc, mval, arm->edbo, 1, &selmask);
01840         if (nearBone) {
01841 
01842                 if (!extend)
01843                         ED_armature_deselect_all(obedit, 0);
01844                 
01845                 /* by definition the non-root connected bones have no root point drawn,
01846                    so a root selection needs to be delivered to the parent tip */
01847                 
01848                 if(selmask & BONE_SELECTED) {
01849                         if(nearBone->parent && (nearBone->flag & BONE_CONNECTED)) {
01850                                 /* click in a chain */
01851                                 if(extend) {
01852                                         /* hold shift inverts this bone's selection */
01853                                         if(nearBone->flag & BONE_SELECTED) {
01854                                                 /* deselect this bone */
01855                                                 nearBone->flag &= ~(BONE_TIPSEL|BONE_SELECTED);
01856                                                 /* only deselect parent tip if it is not selected */
01857                                                 if(!(nearBone->parent->flag & BONE_SELECTED))
01858                                                         nearBone->parent->flag &= ~BONE_TIPSEL;
01859                                         }
01860                                         else {
01861                                                 /* select this bone */
01862                                                 nearBone->flag |= BONE_TIPSEL;
01863                                                 nearBone->parent->flag |= BONE_TIPSEL;
01864                                         }
01865                                 }
01866                                 else {
01867                                         /* select this bone */
01868                                         nearBone->flag |= BONE_TIPSEL;
01869                                         nearBone->parent->flag |= BONE_TIPSEL;
01870                                 }
01871                         }
01872                         else {
01873                                 if(extend) {
01874                                         /* hold shift inverts this bone's selection */
01875                                         if(nearBone->flag & BONE_SELECTED)
01876                                            nearBone->flag &= ~(BONE_TIPSEL|BONE_ROOTSEL);
01877                                         else
01878                                                 nearBone->flag |= (BONE_TIPSEL|BONE_ROOTSEL);
01879                                 }
01880                                 else nearBone->flag |= (BONE_TIPSEL|BONE_ROOTSEL);
01881                         }
01882                 }
01883                 else {
01884                         if (extend && (nearBone->flag & selmask))
01885                                 nearBone->flag &= ~selmask;
01886                         else
01887                                 nearBone->flag |= selmask;
01888                 }
01889                 
01890                 ED_armature_sync_selection(arm->edbo);
01891                 
01892                 if(nearBone) {
01893                         /* then now check for active status */
01894                         if(ebone_select_flag(nearBone)) {
01895                                 arm->act_edbone= nearBone;
01896                         }
01897                 }
01898                 
01899                 WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, vc.obedit);
01900                 return 1;
01901         }
01902 
01903         return 0;
01904 }
01905 
01906 void ED_armature_edit_free(struct Object *ob)
01907 {
01908         bArmature *arm= ob->data;
01909         EditBone *eBone;
01910         
01911         /*      Clear the editbones list */
01912         if (arm->edbo) {
01913                 if (arm->edbo->first) {
01914                         for (eBone=arm->edbo->first; eBone; eBone=eBone->next) {
01915                                 if (eBone->prop) {
01916                                         IDP_FreeProperty(eBone->prop);
01917                                         MEM_freeN(eBone->prop);
01918                                 }
01919                         }
01920 
01921                         BLI_freelistN(arm->edbo);
01922                 }
01923                 MEM_freeN(arm->edbo);
01924                 arm->edbo= NULL;
01925         }
01926 }
01927 
01928 /* Put armature in EditMode */
01929 void ED_armature_to_edit(Object *ob)
01930 {
01931         bArmature *arm= ob->data;
01932         
01933         ED_armature_edit_free(ob);
01934         arm->edbo= MEM_callocN(sizeof(ListBase), "edbo armature");
01935         arm->act_edbone= make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone);
01936         arm->act_bone= NULL;
01937 
01938 //      BIF_freeTemplates(); /* force template update when entering editmode */
01939 }
01940 
01941 
01942 /* adjust bone roll to align Z axis with vector
01943  * vec is in local space and is normalized
01944  */
01945 
01946 float ED_rollBoneToVector(EditBone *bone, const float align_axis[3], const short axis_only)
01947 {
01948         float mat[3][3], nor[3];
01949 
01950         sub_v3_v3v3(nor, bone->tail, bone->head);
01951         vec_roll_to_mat3(nor, 0.0f, mat);
01952 
01953         /* check the bone isnt aligned with the axis */
01954         if(!is_zero_v3(align_axis) && angle_v3v3(align_axis, mat[2]) > FLT_EPSILON) {
01955                 float vec[3], align_axis_proj[3], roll;
01956 
01957                 /* project the new_up_axis along the normal */
01958                 project_v3_v3v3(vec, align_axis, nor);
01959                 sub_v3_v3v3(align_axis_proj, align_axis, vec);
01960                 
01961                 if(axis_only) {
01962                         if(angle_v3v3(align_axis_proj, mat[2]) > (float)(M_PI/2.0)) {
01963                                 negate_v3(align_axis_proj);
01964                         }
01965                 }
01966                 
01967                 roll = angle_v3v3(align_axis_proj, mat[2]);
01968                 
01969                 cross_v3_v3v3(vec, mat[2], align_axis_proj);
01970                 
01971                 if (dot_v3v3(vec, nor) < 0) {
01972                         roll = -roll;
01973                 }
01974 
01975                 return roll;
01976         }
01977 
01978         return 0.0f;
01979 }
01980 
01981 
01982 static EnumPropertyItem prop_calc_roll_types[] = {
01983         {0, "X", 0, "X Axis", ""},
01984         {1, "Y", 0, "Y Axis", ""},
01985         {2, "Z", 0, "Z Axis", ""},
01986         {5, "ACTIVE", 0, "Active Bone", ""},
01987         {6, "VIEW", 0, "View Axis", ""},
01988         {7, "CURSOR", 0, "Cursor", ""},
01989         {0, NULL, 0, NULL, NULL}
01990 };
01991 
01992 
01993 static int armature_calc_roll_exec(bContext *C, wmOperator *op) 
01994 {
01995         Object *ob= CTX_data_edit_object(C);
01996         const short type= RNA_enum_get(op->ptr, "type");
01997         const short axis_only= RNA_boolean_get(op->ptr, "axis_only");
01998         const short axis_flip= RNA_boolean_get(op->ptr, "axis_flip");
01999 
02000         float imat[3][3];
02001 
02002         bArmature *arm= ob->data;
02003         EditBone *ebone;
02004 
02005         copy_m3_m4(imat, ob->obmat);
02006         invert_m3(imat);
02007 
02008         if(type==7) { /* Cursor */
02009                 Scene *scene= CTX_data_scene(C);
02010                 View3D *v3d= CTX_wm_view3d(C); /* can be NULL */
02011                 float cursor_local[3];
02012                 float   *cursor= give_cursor(scene, v3d);
02013         
02014 
02015                 copy_v3_v3(cursor_local, cursor);
02016                 mul_m3_v3(imat, cursor_local);
02017 
02018                 /* cursor */
02019                 for(ebone= arm->edbo->first; ebone; ebone= ebone->next) {
02020                         if(EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
02021                                 float cursor_rel[3];
02022                                 sub_v3_v3v3(cursor_rel, cursor_local, ebone->head);
02023                                 if(axis_flip) negate_v3(cursor_rel);
02024                                 ebone->roll= ED_rollBoneToVector(ebone, cursor_rel, axis_only);
02025                         }
02026                 }
02027         }
02028         else {
02029                 float vec[3]= {0.0f, 0.0f, 0.0f};
02030                 if(type==6) { /* View */
02031                         RegionView3D *rv3d= CTX_wm_region_view3d(C);
02032                         if(rv3d==NULL) {
02033                                 BKE_report(op->reports, RPT_ERROR, "No region view3d available");
02034                                 return OPERATOR_CANCELLED;
02035                         }
02036 
02037                         copy_v3_v3(vec, rv3d->viewinv[2]);
02038                         mul_m3_v3(imat, vec);
02039                 }
02040                 else if (type==5) {
02041                         float mat[3][3], nor[3];
02042                         ebone= (EditBone *)arm->act_edbone;
02043                         if(ebone==NULL) {
02044                                 BKE_report(op->reports, RPT_ERROR, "No active bone set");
02045                                 return OPERATOR_CANCELLED;
02046                         }
02047 
02048                         sub_v3_v3v3(nor, ebone->tail, ebone->head);
02049                         vec_roll_to_mat3(nor, ebone->roll, mat);                        
02050                         copy_v3_v3(vec, mat[2]);
02051                 }
02052                 else { /* Axis */
02053                         assert(type >= 0 && type <= 5);
02054                         if(type<3)      vec[type]= 1.0f; 
02055                         else            vec[type-2]= -1.0f; 
02056                         mul_m3_v3(imat, vec);
02057                 }
02058 
02059                 if(axis_flip) negate_v3(vec);
02060 
02061                 for(ebone= arm->edbo->first; ebone; ebone= ebone->next) {
02062                         if(EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) {
02063                                 /* roll func is a callback which assumes that all is well */
02064                                 ebone->roll= ED_rollBoneToVector(ebone, vec, axis_only);
02065                         }
02066                 }
02067         }
02068 
02069         if (arm->flag & ARM_MIRROR_EDIT) {
02070                 for(ebone= arm->edbo->first; ebone; ebone= ebone->next) {
02071                         if((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) {
02072                                 EditBone *ebone_mirr= ED_armature_bone_get_mirrored(arm->edbo, ebone);
02073                                 if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) {
02074                                         ebone->roll= -ebone_mirr->roll;
02075                                 }
02076                         }
02077                 }
02078         }
02079 
02080         /* note, notifier might evolve */
02081         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
02082         
02083         return OPERATOR_FINISHED;
02084 }
02085 
02086 void ARMATURE_OT_calculate_roll(wmOperatorType *ot)
02087 {
02088         /* identifiers */
02089         ot->name= "Recalculate Roll";
02090         ot->idname= "ARMATURE_OT_calculate_roll";
02091         ot->description= "Automatically fix alignment of select bones' axes";
02092         
02093         /* api callbacks */
02094         ot->invoke = WM_menu_invoke;
02095         ot->exec = armature_calc_roll_exec;
02096         ot->poll = ED_operator_editarmature;
02097         
02098         /* flags */
02099         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
02100 
02101         /* properties */
02102         ot->prop= RNA_def_enum(ot->srna, "type", prop_calc_roll_types, 0, "Type", "");
02103         RNA_def_boolean(ot->srna, "axis_flip", 0, "Flip Axis", "Negate the alignment axis.");
02104         RNA_def_boolean(ot->srna, "axis_only", 0, "Shortest Rotation", "Ignore the axis direction, use the shortest rotation to align.");
02105 }
02106 
02107 /* **************** undo for armatures ************** */
02108 
02109 typedef struct UndoArmature {
02110         EditBone *act_edbone;
02111         ListBase lb;
02112 } UndoArmature;
02113 
02114 static void undoBones_to_editBones(void *uarmv, void *armv)
02115 {
02116         UndoArmature *uarm= uarmv;
02117         bArmature *arm= armv;
02118         EditBone *ebo, *newebo;
02119         
02120         BLI_freelistN(arm->edbo);
02121         
02122         /* copy  */
02123         for(ebo= uarm->lb.first; ebo; ebo= ebo->next) {
02124                 newebo= MEM_dupallocN(ebo);
02125                 ebo->temp= newebo;
02126                 BLI_addtail(arm->edbo, newebo);
02127         }
02128         
02129         /* active bone */
02130         if(uarm->act_edbone) {
02131                 ebo= uarm->act_edbone;
02132                 arm->act_edbone= ebo->temp;
02133         }
02134         else
02135                 arm->act_edbone= NULL;
02136 
02137         /* set pointers */
02138         for(newebo= arm->edbo->first; newebo; newebo= newebo->next) {
02139                 if(newebo->parent) newebo->parent= newebo->parent->temp;
02140         }
02141         /* be sure they dont hang ever */
02142         for(newebo= arm->edbo->first; newebo; newebo= newebo->next) {
02143                 newebo->temp= NULL;
02144         }
02145 }
02146 
02147 static void *editBones_to_undoBones(void *armv)
02148 {
02149         bArmature *arm= armv;
02150         UndoArmature *uarm;
02151         EditBone *ebo, *newebo;
02152         
02153         uarm= MEM_callocN(sizeof(UndoArmature), "listbase undo");
02154         
02155         /* copy */
02156         for(ebo= arm->edbo->first; ebo; ebo= ebo->next) {
02157                 newebo= MEM_dupallocN(ebo);
02158                 ebo->temp= newebo;
02159                 BLI_addtail(&uarm->lb, newebo);
02160         }
02161         
02162         /* active bone */
02163         if(arm->act_edbone) {
02164                 ebo= arm->act_edbone;
02165                 uarm->act_edbone= ebo->temp;
02166         }
02167 
02168         /* set pointers */
02169         for(newebo= uarm->lb.first; newebo; newebo= newebo->next) {
02170                 if(newebo->parent) newebo->parent= newebo->parent->temp;
02171         }
02172         
02173         return uarm;
02174 }
02175 
02176 static void free_undoBones(void *uarmv)
02177 {
02178         UndoArmature *uarm= uarmv;
02179         
02180         BLI_freelistN(&uarm->lb);
02181         MEM_freeN(uarm);
02182 }
02183 
02184 static void *get_armature_edit(bContext *C)
02185 {
02186         Object *obedit= CTX_data_edit_object(C);
02187         if(obedit && obedit->type==OB_ARMATURE) {
02188                 return obedit->data;
02189         }
02190         return NULL;
02191 }
02192 
02193 /* and this is all the undo system needs to know */
02194 void undo_push_armature(bContext *C, const char *name)
02195 {
02196         // XXX solve getdata()
02197         undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL);
02198 }
02199 
02200 
02201 
02202 /* **************** END EditMode stuff ********************** */
02203 /* *************** Adding stuff in editmode *************** */
02204 
02205 /* default bone add, returns it selected, but without tail set */
02206 EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name)
02207 {
02208         EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
02209         
02210         BLI_strncpy(bone->name, name, sizeof(bone->name));
02211         unique_editbone_name(arm->edbo, bone->name, NULL);
02212         
02213         BLI_addtail(arm->edbo, bone);
02214         
02215         bone->flag |= BONE_TIPSEL;
02216         bone->weight= 1.0f;
02217         bone->dist= 0.25f;
02218         bone->xwidth= 0.1f;
02219         bone->zwidth= 0.1f;
02220         bone->ease1= 1.0f;
02221         bone->ease2= 1.0f;
02222         bone->rad_head= 0.10f;
02223         bone->rad_tail= 0.05f;
02224         bone->segments= 1;
02225         bone->layer= arm->layer;
02226         
02227         return bone;
02228 }
02229 
02230 /* v3d and rv3d are allowed to be NULL */
02231 void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d)
02232 {
02233         Object *obedit= scene->obedit; // XXX get from context
02234         bArmature *arm= obedit->data;
02235         float           obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
02236         EditBone        *bone;
02237 
02238         /* Get inverse point for head and orientation for tail */
02239         invert_m4_m4(obedit->imat, obedit->obmat);
02240         mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d));
02241 
02242         if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
02243                 copy_m3_m4(obmat, rv3d->viewmat);
02244         else unit_m3(obmat);
02245         
02246         copy_m3_m4(viewmat, obedit->obmat);
02247         mul_m3_m3m3(totmat, obmat, viewmat);
02248         invert_m3_m3(imat, totmat);
02249         
02250         ED_armature_deselect_all(obedit, 0);
02251         
02252         /*      Create a bone   */
02253         bone= ED_armature_edit_bone_add(arm, "Bone");
02254 
02255         arm->act_edbone= bone;
02256 
02257         copy_v3_v3(bone->head, curs);
02258         
02259         if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
02260                 add_v3_v3v3(bone->tail, bone->head, imat[1]);   // bone with unit length 1
02261         else
02262                 add_v3_v3v3(bone->tail, bone->head, imat[2]);   // bone with unit length 1, pointing up Z
02263         
02264 }
02265 
02266 
02267 /* previously addvert_armature */
02268 /* the ctrl-click method */
02269 static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
02270 {
02271         View3D *v3d;
02272         bArmature *arm;
02273         EditBone *ebone, *newbone, *flipbone;
02274         float *curs, mat[3][3],imat[3][3];
02275         int a, to_root= 0;
02276         Object *obedit;
02277         Scene *scene;
02278 
02279         scene = CTX_data_scene(C);
02280         v3d= CTX_wm_view3d(C);
02281         obedit= CTX_data_edit_object(C);
02282         arm= obedit->data;
02283         
02284         /* find the active or selected bone */
02285         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
02286                 if (EBONE_VISIBLE(arm, ebone)) {
02287                         if (ebone->flag & BONE_TIPSEL || arm->act_edbone == ebone)
02288                                 break;
02289                 }
02290         }
02291         
02292         if (ebone==NULL) {
02293                 for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
02294                         if (EBONE_VISIBLE(arm, ebone)) {
02295                                 if (ebone->flag & BONE_ROOTSEL || arm->act_edbone == ebone)
02296                                         break;
02297                         }
02298                 }
02299                 if (ebone == NULL) 
02300                         return OPERATOR_CANCELLED;
02301                 
02302                 to_root= 1;
02303         }
02304         
02305         ED_armature_deselect_all(obedit, 0);
02306         
02307         /* we re-use code for mirror editing... */
02308         flipbone= NULL;
02309         if (arm->flag & ARM_MIRROR_EDIT)
02310                 flipbone= ED_armature_bone_get_mirrored(arm->edbo, ebone);
02311 
02312         for (a=0; a<2; a++) {
02313                 if (a==1) {
02314                         if (flipbone==NULL)
02315                                 break;
02316                         else {
02317                                 SWAP(EditBone *, flipbone, ebone);
02318                         }
02319                 }
02320                 
02321                 newbone= ED_armature_edit_bone_add(arm, ebone->name);
02322                 arm->act_edbone= newbone;
02323                 
02324                 if (to_root) {
02325                         copy_v3_v3(newbone->head, ebone->head);
02326                         newbone->rad_head= ebone->rad_tail;
02327                         newbone->parent= ebone->parent;
02328                 }
02329                 else {
02330                         copy_v3_v3(newbone->head, ebone->tail);
02331                         newbone->rad_head= ebone->rad_tail;
02332                         newbone->parent= ebone;
02333                         newbone->flag |= BONE_CONNECTED;
02334                 }
02335                 
02336                 curs= give_cursor(scene, v3d);
02337                 copy_v3_v3(newbone->tail, curs);
02338                 sub_v3_v3v3(newbone->tail, newbone->tail, obedit->obmat[3]);
02339                 
02340                 if (a==1) 
02341                         newbone->tail[0]= -newbone->tail[0];
02342                 
02343                 copy_m3_m4(mat, obedit->obmat);
02344                 invert_m3_m3(imat, mat);
02345                 mul_m3_v3(imat, newbone->tail);
02346                 
02347                 newbone->length= len_v3v3(newbone->head, newbone->tail);
02348                 newbone->rad_tail= newbone->length*0.05f;
02349                 newbone->dist= newbone->length*0.25f;
02350                 
02351         }
02352         
02353         ED_armature_sync_selection(arm->edbo);
02354 
02355         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
02356         
02357         return OPERATOR_FINISHED;
02358 }
02359 
02360 static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
02361 {
02362         /* TODO most of this code is copied from set3dcursor_invoke,
02363            it would be better to reuse code in set3dcursor_invoke */
02364 
02365         /* temporarily change 3d cursor position */
02366         Scene *scene;
02367         ARegion *ar;
02368         View3D *v3d;
02369         float *fp = NULL, tvec[3], oldcurs[3], mval_f[2];
02370         int retv;
02371 
02372         scene= CTX_data_scene(C);
02373         ar= CTX_wm_region(C);
02374         v3d = CTX_wm_view3d(C);
02375         
02376         fp= give_cursor(scene, v3d);
02377         
02378         copy_v3_v3(oldcurs, fp);
02379 
02380         VECCOPY2D(mval_f, event->mval);
02381         ED_view3d_win_to_3d(ar, fp, mval_f, tvec);
02382         copy_v3_v3(fp, tvec);
02383 
02384         /* extrude to the where new cursor is and store the operation result */
02385         retv= armature_click_extrude_exec(C, op);
02386 
02387         /* restore previous 3d cursor position */
02388         copy_v3_v3(fp, oldcurs);
02389 
02390         return retv;
02391 }
02392 
02393 void ARMATURE_OT_click_extrude(wmOperatorType *ot)
02394 {
02395         /* identifiers */
02396         ot->name= "Click-Extrude";
02397         ot->idname= "ARMATURE_OT_click_extrude";
02398         ot->description= "Create a new bone going from the last selected joint to the mouse position";
02399         
02400         /* api callbacks */
02401         ot->invoke = armature_click_extrude_invoke;
02402         ot->exec = armature_click_extrude_exec;
02403         ot->poll = ED_operator_editarmature;
02404         
02405         /* flags */
02406         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
02407 
02408         /* props */
02409 }
02410 
02411 /* adds an EditBone between the nominated locations (should be in the right space) */
02412 static EditBone *add_points_bone (Object *obedit, float head[], float tail[]) 
02413 {
02414         EditBone *ebo;
02415         
02416         ebo= ED_armature_edit_bone_add(obedit->data, "Bone");
02417         
02418         copy_v3_v3(ebo->head, head);
02419         copy_v3_v3(ebo->tail, tail);
02420         
02421         return ebo;
02422 }
02423 
02424 
02425 static EditBone *get_named_editbone(ListBase *edbo, char *name)
02426 {
02427         EditBone  *eBone;
02428 
02429         if (name) {
02430                 for (eBone=edbo->first; eBone; eBone=eBone->next) {
02431                         if (!strcmp(name, eBone->name))
02432                                 return eBone;
02433                 }
02434         }
02435 
02436         return NULL;
02437 }
02438 
02439 /* Call this before doing any duplications
02440  * */
02441 void preEditBoneDuplicate(ListBase *editbones)
02442 {
02443         EditBone *eBone;
02444         
02445         /* clear temp */
02446         for (eBone = editbones->first; eBone; eBone = eBone->next)
02447         {
02448                 eBone->temp = NULL;
02449         }
02450 }
02451 
02452 /*
02453  * Note: When duplicating cross objects, editbones here is the list of bones
02454  * from the SOURCE object but ob is the DESTINATION object
02455  * */
02456 void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Object *src_ob, Object *dst_ob)
02457 {
02458         /* If an edit bone has been duplicated, lets
02459          * update it's constraints if the subtarget
02460          * they point to has also been duplicated
02461          */
02462         EditBone     *oldtarget, *newtarget;
02463         bPoseChannel *pchan;
02464         bConstraint  *curcon;
02465         ListBase     *conlist;
02466         
02467         if ( (pchan = verify_pose_channel(dst_ob->pose, dupBone->name)) ) {
02468                 if ( (conlist = &pchan->constraints) ) {
02469                         for (curcon = conlist->first; curcon; curcon=curcon->next) {
02470                                 /* does this constraint have a subtarget in
02471                                  * this armature?
02472                                  */
02473                                 bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
02474                                 ListBase targets = {NULL, NULL};
02475                                 bConstraintTarget *ct;
02476                                 
02477                                 if (cti && cti->get_constraint_targets) {
02478                                         cti->get_constraint_targets(curcon, &targets);
02479                                         
02480                                         for (ct= targets.first; ct; ct= ct->next) {
02481                                                 if ((ct->tar == src_ob) && (ct->subtarget[0])) {
02482                                                         ct->tar = dst_ob; /* update target */ 
02483                                                         oldtarget = get_named_editbone(editbones, ct->subtarget);
02484                                                         if (oldtarget) {
02485                                                                 /* was the subtarget bone duplicated too? If
02486                                                                  * so, update the constraint to point at the 
02487                                                                  * duplicate of the old subtarget.
02488                                                                  */
02489                                                                 if (oldtarget->temp) {
02490                                                                         newtarget = (EditBone *) oldtarget->temp;
02491                                                                         strcpy(ct->subtarget, newtarget->name);
02492                                                                 }
02493                                                         }
02494                                                 }
02495                                         }
02496                                         
02497                                         if (cti->flush_constraint_targets)
02498                                                 cti->flush_constraint_targets(curcon, &targets, 0);
02499                                 }
02500                         }
02501                 }
02502         }
02503 }
02504 
02505 void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob)
02506 {
02507         updateDuplicateSubtargetObjects(dupBone, editbones, ob, ob);
02508 }
02509 
02510 
02511 EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
02512 {
02513         EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone");
02514         
02515         /*      Copy data from old bone to new bone */
02516         memcpy(eBone, curBone, sizeof(EditBone));
02517         
02518         curBone->temp = eBone;
02519         eBone->temp = curBone;
02520         
02521         if (name != NULL)
02522         {
02523                 BLI_strncpy(eBone->name, name, sizeof(eBone->name));
02524         }
02525 
02526         unique_editbone_name(editbones, eBone->name, NULL);
02527         BLI_addtail(editbones, eBone);
02528         
02529         /* copy the ID property */
02530         if(curBone->prop)
02531                 eBone->prop= IDP_CopyProperty(curBone->prop);
02532 
02533         /* Lets duplicate the list of constraints that the
02534          * current bone has.
02535          */
02536         if (src_ob->pose) {
02537                 bPoseChannel *chanold, *channew;
02538                 
02539                 chanold = verify_pose_channel(src_ob->pose, curBone->name);
02540                 if (chanold) {
02541                         /* WARNING: this creates a new posechannel, but there will not be an attached bone
02542                          *              yet as the new bones created here are still 'EditBones' not 'Bones'.
02543                          */
02544                         channew= verify_pose_channel(dst_ob->pose, eBone->name);
02545 
02546                         if(channew) {
02547                                 duplicate_pose_channel_data(channew, chanold);
02548                         }
02549                 }
02550         }
02551         
02552         return eBone;
02553 }
02554 
02555 EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob)
02556 {
02557         return duplicateEditBoneObjects(curBone, name, editbones, ob, ob);
02558 }
02559 
02560 /* previously adduplicate_armature */
02561 static int armature_duplicate_selected_exec(bContext *C, wmOperator *UNUSED(op))
02562 {
02563         bArmature *arm;
02564         EditBone        *eBone = NULL;
02565         EditBone        *curBone;
02566         EditBone        *firstDup=NULL; /*      The beginning of the duplicated bones in the edbo list */
02567 
02568         Object *obedit= CTX_data_edit_object(C);
02569         arm= obedit->data;
02570 
02571         /* cancel if nothing selected */
02572         if (CTX_DATA_COUNT(C, selected_bones) == 0)
02573                 return OPERATOR_CANCELLED;
02574         
02575         ED_armature_sync_selection(arm->edbo); // XXX why is this needed?
02576 
02577         preEditBoneDuplicate(arm->edbo);
02578 
02579         /* Select mirrored bones */
02580         if (arm->flag & ARM_MIRROR_EDIT) {
02581                 for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
02582                         if (EBONE_VISIBLE(arm, curBone)) {
02583                                 if (curBone->flag & BONE_SELECTED) {
02584                                         eBone = ED_armature_bone_get_mirrored(arm->edbo, curBone);
02585                                         if (eBone)
02586                                                 eBone->flag |= BONE_SELECTED;
02587                                 }
02588                         }
02589                 }
02590         }
02591 
02592         
02593         /*      Find the selected bones and duplicate them as needed */
02594         for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
02595                 if (EBONE_VISIBLE(arm, curBone)) {
02596                         if (curBone->flag & BONE_SELECTED) {
02597                                 
02598                                 eBone= duplicateEditBone(curBone, curBone->name, arm->edbo, obedit);
02599                                 
02600                                 if (!firstDup)
02601                                         firstDup=eBone;
02602 
02603                         }
02604                 }
02605         }
02606 
02607         /*      Run though the list and fix the pointers */
02608         for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
02609                 if (EBONE_VISIBLE(arm, curBone)) {
02610                         if (curBone->flag & BONE_SELECTED) {
02611                                 eBone=(EditBone*) curBone->temp;
02612                                 
02613                                 if (!curBone->parent) {
02614                                         /* If this bone has no parent,
02615                                          * Set the duplicate->parent to NULL
02616                                          */
02617                                         eBone->parent = NULL;
02618                                 }
02619                                 else if (curBone->parent->temp) {
02620                                         /* If this bone has a parent that was duplicated,
02621                                          * Set the duplicate->parent to the curBone->parent->temp
02622                                          */
02623                                         eBone->parent= (EditBone *)curBone->parent->temp;
02624                                 }
02625                                 else {
02626                                         /* If this bone has a parent that IS not selected,
02627                                          * Set the duplicate->parent to the curBone->parent
02628                                          */
02629                                         eBone->parent=(EditBone*) curBone->parent; 
02630                                         eBone->flag &= ~BONE_CONNECTED;
02631                                 }
02632                                 
02633                                 /* Lets try to fix any constraint subtargets that might
02634                                  * have been duplicated 
02635                                  */
02636                                 updateDuplicateSubtarget(eBone, arm->edbo, obedit);
02637                         }
02638                 }
02639         } 
02640         
02641         /* correct the active bone */
02642         if(arm->act_edbone) {
02643                 eBone= arm->act_edbone;
02644                 if(eBone->temp)
02645                         arm->act_edbone= eBone->temp;
02646         }
02647 
02648         /*      Deselect the old bones and select the new ones */
02649         for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
02650                 if (EBONE_VISIBLE(arm, curBone))
02651                         curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
02652         }
02653 
02654         ED_armature_validate_active(arm);
02655 
02656         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
02657         
02658         return OPERATOR_FINISHED;
02659 }
02660 
02661 
02662 void ARMATURE_OT_duplicate(wmOperatorType *ot)
02663 {
02664         /* identifiers */
02665         ot->name= "Duplicate Selected Bone(s)";
02666         ot->idname= "ARMATURE_OT_duplicate";
02667         ot->description= "Make copies of the selected bones within the same armature";
02668         
02669         /* api callbacks */
02670         ot->exec = armature_duplicate_selected_exec;
02671         ot->poll = ED_operator_editarmature;
02672         
02673         /* flags */
02674         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
02675 }
02676 
02677 
02678 /* *************** END Adding stuff in editmode *************** */
02679 /* ************** Add/Remove stuff in editmode **************** */
02680 
02681 /* temporary data-structure for merge/fill bones */
02682 typedef struct EditBonePoint {
02683         struct EditBonePoint *next, *prev;
02684         
02685         EditBone *head_owner;           /* EditBone which uses this point as a 'head' point */
02686         EditBone *tail_owner;           /* EditBone which uses this point as a 'tail' point */
02687         
02688         float vec[3];                           /* the actual location of the point in local/EditMode space */
02689 } EditBonePoint;
02690 
02691 /* find chain-tips (i.e. bones without children) */
02692 static void chains_find_tips (ListBase *edbo, ListBase *list)
02693 {
02694         EditBone *curBone, *ebo;
02695         LinkData *ld;
02696         
02697         /* note: this is potentially very slow ... there's got to be a better way */
02698         for (curBone= edbo->first; curBone; curBone= curBone->next) {
02699                 short stop= 0;
02700                 
02701                 /* is this bone contained within any existing chain? (skip if so) */
02702                 for (ld= list->first; ld; ld= ld->next) {
02703                         for (ebo= ld->data; ebo; ebo= ebo->parent) {
02704                                 if (ebo == curBone) {
02705                                         stop= 1;
02706                                         break;
02707                                 }
02708                         }
02709                         
02710                         if (stop) break;
02711                 }
02712                 /* skip current bone if it is part of an existing chain */
02713                 if (stop) continue;
02714                 
02715                 /* is any existing chain part of the chain formed by this bone? */
02716                 stop= 0;
02717                 for (ebo= curBone->parent; ebo; ebo= ebo->parent) {
02718                         for (ld= list->first; ld; ld= ld->next) {
02719                                 if (ld->data == ebo) {
02720                                         ld->data= curBone;
02721                                         stop= 1;
02722                                         break;
02723                                 }
02724                         }
02725                         
02726                         if (stop) break;
02727                 }
02728                 /* current bone has already been added to a chain? */
02729                 if (stop) continue;
02730                 
02731                 /* add current bone to a new chain */
02732                 ld= MEM_callocN(sizeof(LinkData), "BoneChain");
02733                 ld->data= curBone;
02734                 BLI_addtail(list, ld);
02735         }
02736 }
02737 
02738 /* --------------------- */
02739 
02740 static void fill_add_joint (EditBone *ebo, short eb_tail, ListBase *points)
02741 {
02742         EditBonePoint *ebp;
02743         float vec[3];
02744         short found= 0;
02745         
02746         if (eb_tail) {
02747                 copy_v3_v3(vec, ebo->tail);
02748         }
02749         else {
02750                 copy_v3_v3(vec, ebo->head);
02751         }
02752         
02753         for (ebp= points->first; ebp; ebp= ebp->next) {
02754                 if (equals_v3v3(ebp->vec, vec)) {                       
02755                         if (eb_tail) {
02756                                 if ((ebp->head_owner) && (ebp->head_owner->parent == ebo)) {
02757                                         /* so this bone's tail owner is this bone */
02758                                         ebp->tail_owner= ebo;
02759                                         found= 1;
02760                                         break;
02761                                 }
02762                         }
02763                         else {
02764                                 if ((ebp->tail_owner) && (ebo->parent == ebp->tail_owner)) {
02765                                         /* so this bone's head owner is this bone */
02766                                         ebp->head_owner= ebo;
02767                                         found = 1;
02768                                         break;
02769                                 }
02770                         }
02771                 }
02772         }
02773         
02774         /* allocate a new point if no existing point was related */
02775         if (found == 0) {
02776                 ebp= MEM_callocN(sizeof(EditBonePoint), "EditBonePoint");
02777                 
02778                 if (eb_tail) {
02779                         copy_v3_v3(ebp->vec, ebo->tail);
02780                         ebp->tail_owner= ebo;
02781                 }
02782                 else {
02783                         copy_v3_v3(ebp->vec, ebo->head);
02784                         ebp->head_owner= ebo;
02785                 }
02786                 
02787                 BLI_addtail(points, ebp);
02788         }
02789 }
02790 
02791 /* bone adding between selected joints */
02792 static int armature_fill_bones_exec (bContext *C, wmOperator *op)
02793 {
02794         Object *obedit= CTX_data_edit_object(C);
02795         bArmature *arm= (obedit) ? obedit->data : NULL;
02796         Scene *scene= CTX_data_scene(C);
02797         View3D *v3d= CTX_wm_view3d(C);
02798         ListBase points = {NULL, NULL};
02799         int count;
02800 
02801         /* sanity checks */
02802         if (ELEM(NULL, obedit, arm))
02803                 return OPERATOR_CANCELLED;
02804 
02805         /* loop over all bones, and only consider if visible */
02806         CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones)
02807         {
02808                 if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL))
02809                         fill_add_joint(ebone, 0, &points);
02810                 if (ebone->flag & BONE_TIPSEL) 
02811                         fill_add_joint(ebone, 1, &points);
02812         }
02813         CTX_DATA_END;
02814         
02815         /* the number of joints determines how we fill:
02816          *      1) between joint and cursor (joint=head, cursor=tail)
02817          *      2) between the two joints (order is dependent on active-bone/hierachy)
02818          *      3+) error (a smarter method involving finding chains needs to be worked out
02819          */
02820         count= BLI_countlist(&points);
02821         
02822         if (count == 0) {
02823                 BKE_report(op->reports, RPT_ERROR, "No joints selected");
02824                 return OPERATOR_CANCELLED;
02825         }
02826         else if (count == 1) {
02827                 EditBonePoint *ebp;
02828                 float curs[3];
02829                 
02830                 /* Get Points - selected joint */
02831                 ebp= (EditBonePoint *)points.first;
02832                 
02833                 /* Get points - cursor (tail) */
02834                 invert_m4_m4(obedit->imat, obedit->obmat);
02835                 mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d));
02836                 
02837                 /* Create a bone */
02838                 /* newbone= */ add_points_bone(obedit, ebp->vec, curs);
02839         }
02840         else if (count == 2) {
02841                 EditBonePoint *ebp, *ebp2;
02842                 float head[3], tail[3];
02843                 short headtail = 0;
02844                 
02845                 /* check that the points don't belong to the same bone */
02846                 ebp= (EditBonePoint *)points.first;
02847                 ebp2= ebp->next;
02848                 
02849                 if ((ebp->head_owner==ebp2->tail_owner) && (ebp->head_owner!=NULL)) {
02850                         BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
02851                         BLI_freelistN(&points);
02852                         return OPERATOR_CANCELLED;
02853                 }
02854                 if ((ebp->tail_owner==ebp2->head_owner) && (ebp->tail_owner!=NULL)) {
02855                         BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
02856                         BLI_freelistN(&points);
02857                         return OPERATOR_CANCELLED;
02858                 }
02859                 
02860                 /* find which one should be the 'head' */
02861                 if ((ebp->head_owner && ebp2->head_owner) || (ebp->tail_owner && ebp2->tail_owner)) {
02862                         /* rule: whichever one is closer to 3d-cursor */
02863                         float curs[3];
02864                         float vecA[3], vecB[3];
02865                         float distA, distB;
02866                         
02867                         /* get cursor location */
02868                         invert_m4_m4(obedit->imat, obedit->obmat);
02869                         mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d));
02870                         
02871                         /* get distances */
02872                         sub_v3_v3v3(vecA, ebp->vec, curs);
02873                         sub_v3_v3v3(vecB, ebp2->vec, curs);
02874                         distA= len_v3(vecA);
02875                         distB= len_v3(vecB);
02876                         
02877                         /* compare distances - closer one therefore acts as direction for bone to go */
02878                         headtail= (distA < distB) ? 2 : 1;
02879                 }
02880                 else if (ebp->head_owner) {
02881                         headtail = 1;
02882                 }
02883                 else if (ebp2->head_owner) {
02884                         headtail = 2;
02885                 }
02886                 
02887                 /* assign head/tail combinations */
02888                 if (headtail == 2) {
02889                         copy_v3_v3(head, ebp->vec);
02890                         copy_v3_v3(tail, ebp2->vec);
02891                 }
02892                 else if (headtail == 1) {
02893                         copy_v3_v3(head, ebp2->vec);
02894                         copy_v3_v3(tail, ebp->vec);
02895                 }
02896                 
02897                 /* add new bone and parent it to the appropriate end */
02898                 if (headtail) {
02899                         EditBone *newbone= add_points_bone(obedit, head, tail);
02900                         
02901                         /* do parenting (will need to set connected flag too) */
02902                         if (headtail == 2) {
02903                                 /* ebp tail or head - tail gets priority */
02904                                 if (ebp->tail_owner)
02905                                         newbone->parent= ebp->tail_owner;
02906                                 else
02907                                         newbone->parent= ebp->head_owner;
02908                         }
02909                         else {
02910                                 /* ebp2 tail or head - tail gets priority */
02911                                 if (ebp2->tail_owner)
02912                                         newbone->parent= ebp2->tail_owner;
02913                                 else
02914                                         newbone->parent= ebp2->head_owner;
02915                         }
02916                         
02917                         newbone->flag |= BONE_CONNECTED;
02918                 }
02919         }
02920         else {
02921                 // FIXME.. figure out a method for multiple bones
02922                 BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d \n", count); 
02923                 BLI_freelistN(&points);
02924                 return OPERATOR_CANCELLED;
02925         }
02926         
02927         /* updates */
02928         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, obedit);
02929         
02930         /* free points */
02931         BLI_freelistN(&points);
02932         
02933         return OPERATOR_FINISHED;
02934 }
02935 
02936 void ARMATURE_OT_fill (wmOperatorType *ot)
02937 {
02938         /* identifiers */
02939         ot->name= "Fill Between Joints";
02940         ot->idname= "ARMATURE_OT_fill";
02941         ot->description= "Add bone between selected joint(s) and/or 3D-Cursor";
02942         
02943         /* callbacks */
02944         ot->exec= armature_fill_bones_exec;
02945         ot->poll= ED_operator_editarmature;
02946         
02947         /* flags */
02948         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
02949 }
02950 
02951 /* --------------------- */
02952 
02953 /* this function merges between two bones, removes them and those in-between, 
02954  * and adjusts the parent relationships for those in-between
02955  */
02956 static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
02957 {
02958         bArmature *arm= obedit->data;
02959         EditBone *ebo, *ebone, *newbone;
02960         LinkData *chain;
02961         float head[3], tail[3];
02962         
02963         /* check if same bone */
02964         if (start == end) {
02965                 if (G.f & G_DEBUG) {
02966                         printf("Error: same bone! \n");
02967                         printf("\tstart = %s, end = %s \n", start->name, end->name);
02968                 }
02969         }
02970         
02971         /* step 1: add a new bone
02972          *      - head = head/tail of start (default head)
02973          *      - tail = head/tail of end (default tail)
02974          *      - parent = parent of start
02975          */
02976         if ((start->flag & BONE_TIPSEL) && (start->flag & BONE_SELECTED)==0) {
02977                 copy_v3_v3(head, start->tail);
02978         }
02979         else {
02980                 copy_v3_v3(head, start->head);
02981         }
02982         if ((end->flag & BONE_ROOTSEL) && (end->flag & BONE_SELECTED)==0) {
02983                 copy_v3_v3(tail, end->head);
02984         }
02985         else {
02986                 copy_v3_v3(tail, end->tail);
02987         }
02988         newbone= add_points_bone(obedit, head, tail);
02989         newbone->parent = start->parent;
02990 
02991         /* TODO, copy more things to the new bone */
02992         newbone->flag= start->flag & (BONE_HINGE|BONE_NO_DEFORM|BONE_NO_SCALE|BONE_NO_CYCLICOFFSET|BONE_NO_LOCAL_LOCATION|BONE_DONE);
02993         
02994         /* step 2a: parent children of in-between bones to newbone */
02995         for (chain= chains->first; chain; chain= chain->next) {
02996                 /* ick: we need to check if parent of each bone in chain is one of the bones in the */
02997                 short found= 0;
02998                 for (ebo= chain->data; ebo; ebo= ebo->parent) {
02999                         
03000                         /* try to find which bone from the list to be removed, is the parent */
03001                         for (ebone= end; ebone; ebone= ebone->parent) {
03002                                 if (ebo->parent == ebone) {
03003                                         found= 1;
03004                                         break;
03005                                 }
03006                         }
03007                         
03008                         /* adjust this bone's parent to newbone then */
03009                         if (found) {
03010                                 ebo->parent= newbone;
03011                                 break;
03012                         }
03013                 }
03014                 if (found) {
03015                         break;
03016                 }
03017         }
03018         
03019         /* step 2b: parent child of end to newbone (child from this chain) */
03020         if (endchild)
03021                 endchild->parent= newbone;
03022         
03023         /* step 3: delete all bones between and including start and end */
03024         for (ebo= end; ebo; ebo= ebone) {
03025                 ebone= (ebo == start) ? (NULL) : (ebo->parent);
03026                 bone_free(arm, ebo);
03027         }
03028         
03029         newbone->flag |= (BONE_ROOTSEL|BONE_TIPSEL|BONE_SELECTED);
03030         ED_armature_sync_selection(arm->edbo);
03031 }
03032 
03033 
03034 static int armature_merge_exec (bContext *C, wmOperator *op)
03035 {
03036         Object *obedit= CTX_data_edit_object(C);
03037         bArmature *arm= (obedit) ? obedit->data : NULL;
03038         short type= RNA_enum_get(op->ptr, "type");
03039         
03040         /* sanity checks */
03041         if ELEM(NULL, obedit, arm)
03042                 return OPERATOR_CANCELLED;
03043         
03044         /* for now, there's only really one type of merging that's performed... */
03045         if (type == 1) {
03046                 /* go down chains, merging bones */
03047                 ListBase chains = {NULL, NULL};
03048                 LinkData *chain, *nchain;
03049                 EditBone *ebo;
03050                 
03051                 /* get chains (ends on chains) */
03052                 chains_find_tips(arm->edbo, &chains);
03053                 if (chains.first == NULL) return OPERATOR_CANCELLED;
03054 
03055                 armature_tag_select_mirrored(arm);
03056 
03057                 /* each 'chain' is the last bone in the chain (with no children) */
03058                 for (chain= chains.first; chain; chain= nchain) {
03059                         EditBone *bstart= NULL, *bend= NULL;
03060                         EditBone *bchild= NULL, *child=NULL;
03061                         
03062                         /* temporarily remove chain from list of chains */
03063                         nchain= chain->next;
03064                         BLI_remlink(&chains, chain);
03065                         
03066                         /* only consider bones that are visible and selected */
03067                         for (ebo=chain->data; ebo; child=ebo, ebo=ebo->parent) {
03068                                 /* check if visible + selected */
03069                                 if ( EBONE_VISIBLE(arm, ebo) &&
03070                                          ((ebo->flag & BONE_CONNECTED) || (ebo->parent==NULL)) &&
03071                                          (ebo->flag & BONE_SELECTED) )
03072                                 {
03073                                         /* set either end or start (end gets priority, unless it is already set) */
03074                                         if (bend == NULL)  {
03075                                                 bend= ebo;
03076                                                 bchild= child;
03077                                         }
03078                                         else 
03079                                                 bstart= ebo;
03080                                 }
03081                                 else {
03082                                         /* chain is broken... merge any continous segments then clear */
03083                                         if (bstart && bend)
03084                                                 bones_merge(obedit, bstart, bend, bchild, &chains);
03085                                         
03086                                         bstart = NULL;
03087                                         bend = NULL;
03088                                         bchild = NULL;
03089                                 }
03090                         }
03091                         
03092                         /* merge from bstart to bend if something not merged */
03093                         if (bstart && bend)
03094                                 bones_merge(obedit, bstart, bend, bchild, &chains);
03095                         
03096                         /* put back link */
03097                         BLI_insertlinkbefore(&chains, nchain, chain);
03098                 }               
03099                 
03100                 armature_tag_unselect(arm);
03101 
03102                 BLI_freelistN(&chains);
03103         }
03104         
03105         /* updates */
03106         ED_armature_sync_selection(arm->edbo);
03107         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, obedit);
03108         
03109         return OPERATOR_FINISHED;
03110 }
03111 
03112 void ARMATURE_OT_merge (wmOperatorType *ot)
03113 {
03114         static EnumPropertyItem merge_types[] = {
03115                 {1, "WITHIN_CHAIN", 0, "Within Chains", ""},
03116                 {0, NULL, 0, NULL, NULL}
03117         };
03118 
03119         /* identifiers */
03120         ot->name= "Merge Bones";
03121         ot->idname= "ARMATURE_OT_merge";
03122         ot->description= "Merge continuous chains of selected bones";
03123         
03124         /* callbacks */
03125         ot->invoke= WM_menu_invoke;
03126         ot->exec= armature_merge_exec;
03127         ot->poll= ED_operator_editarmature;
03128         
03129         /* flags */
03130         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03131         
03132         /* properties */
03133         ot->prop= RNA_def_enum(ot->srna, "type", merge_types, 0, "Type", "");
03134 }
03135 
03136 /* ************** END Add/Remove stuff in editmode ************ */
03137 /* *************** Tools in editmode *********** */
03138 
03139 static int armature_hide_exec(bContext *C, wmOperator *op)
03140 {
03141         Object *obedit= CTX_data_edit_object(C);
03142         bArmature *arm= obedit->data;
03143         EditBone *ebone;
03144         const int invert= RNA_boolean_get(op->ptr, "unselected") ? BONE_SELECTED : 0;
03145 
03146         /* cancel if nothing selected */
03147         if (CTX_DATA_COUNT(C, selected_bones) == 0)
03148                 return OPERATOR_CANCELLED;
03149 
03150         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
03151                 if (EBONE_VISIBLE(arm, ebone)) {
03152                         if ((ebone->flag & BONE_SELECTED) != invert) {
03153                                 ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
03154                                 ebone->flag |= BONE_HIDDEN_A;
03155                         }
03156                 }
03157         }
03158         ED_armature_validate_active(arm);
03159         ED_armature_sync_selection(arm->edbo);
03160 
03161         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
03162 
03163         return OPERATOR_FINISHED;
03164 }
03165 
03166 void ARMATURE_OT_hide(wmOperatorType *ot)
03167 {
03168         /* identifiers */
03169         ot->name= "Hide Selected Bones";
03170         ot->idname= "ARMATURE_OT_hide";
03171         ot->description= "Tag selected bones to not be visible in Edit Mode";
03172         
03173         /* api callbacks */
03174         ot->exec= armature_hide_exec;
03175         ot->poll= ED_operator_editarmature;
03176         
03177         /* flags */
03178         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03179 
03180         /* props */
03181         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected.");
03182 }
03183 
03184 static int armature_reveal_exec(bContext *C, wmOperator *UNUSED(op))
03185 {
03186         Object *obedit= CTX_data_edit_object(C);
03187         bArmature *arm= obedit->data;
03188         EditBone *ebone;
03189         
03190         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
03191                 if(arm->layer & ebone->layer) {
03192                         if (ebone->flag & BONE_HIDDEN_A) {
03193                                 ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
03194                                 ebone->flag &= ~BONE_HIDDEN_A;
03195                         }
03196                 }
03197         }
03198         ED_armature_validate_active(arm);
03199         ED_armature_sync_selection(arm->edbo);
03200 
03201         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
03202 
03203         return OPERATOR_FINISHED;
03204 }
03205 
03206 void ARMATURE_OT_reveal(wmOperatorType *ot)
03207 {
03208         /* identifiers */
03209         ot->name= "Reveal Bones";
03210         ot->idname= "ARMATURE_OT_reveal";
03211         ot->description= "Unhide all bones that have been tagged to be hidden in Edit Mode";
03212         
03213         /* api callbacks */
03214         ot->exec= armature_reveal_exec;
03215         ot->poll= ED_operator_editarmature;
03216         
03217         /* flags */
03218         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03219 
03220 }
03221 #if 0 // remove this?
03222 static void hide_selected_armature_bones(Scene *scene)
03223 {
03224         Object *obedit= scene->obedit; // XXX get from context
03225         bArmature *arm= obedit->data;
03226         EditBone *ebone;
03227         
03228         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
03229                 if (EBONE_VISIBLE(arm, ebone)) {
03230                         if (ebone->flag & BONE_SELECTED) {
03231                                 ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
03232                                 ebone->flag |= BONE_HIDDEN_A;
03233                         }
03234                 }
03235         }
03236         ED_armature_validate_active(arm);
03237         ED_armature_sync_selection(arm->edbo);
03238 }
03239 
03240 static void hide_unselected_armature_bones(Scene *scene)
03241 {
03242         Object *obedit= scene->obedit; // XXX get from context
03243         bArmature *arm= obedit->data;
03244         EditBone *ebone;
03245         
03246         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
03247                 bArmature *arm= obedit->data;
03248                 if (EBONE_VISIBLE(arm, ebone)) {
03249                         if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL));
03250                         else {
03251                                 ebone->flag |= BONE_HIDDEN_A;
03252                         }
03253                 }
03254         }
03255 
03256         ED_armature_validate_active(arm);
03257         ED_armature_sync_selection(arm->edbo);
03258 }
03259 
03260 void show_all_armature_bones(Scene *scene)
03261 {
03262         Object *obedit= scene->obedit; // XXX get from context
03263         bArmature *arm= obedit->data;
03264         EditBone *ebone;
03265         
03266         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
03267                 if(arm->layer & ebone->layer) {
03268                         if (ebone->flag & BONE_HIDDEN_A) {
03269                                 ebone->flag |= (BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
03270                                 ebone->flag &= ~BONE_HIDDEN_A;
03271                         }
03272                 }
03273         }
03274         ED_armature_validate_active(arm);
03275         ED_armature_sync_selection(arm->edbo);
03276 }
03277 #endif
03278 
03279 /* previously extrude_armature */
03280 /* context; editmode armature */
03281 /* if forked && mirror-edit: makes two bones with flipped names */
03282 static int armature_extrude_exec(bContext *C, wmOperator *op)
03283 {
03284         Object *obedit;
03285         bArmature *arm;
03286         EditBone *newbone, *ebone, *flipbone, *first=NULL;
03287         int a, totbone= 0, do_extrude;
03288         int forked = RNA_boolean_get(op->ptr, "forked");
03289 
03290         obedit= CTX_data_edit_object(C);
03291         arm= obedit->data;
03292 
03293         /* since we allow root extrude too, we have to make sure selection is OK */
03294         for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
03295                 if (EBONE_VISIBLE(arm, ebone)) {
03296                         if (ebone->flag & BONE_ROOTSEL) {
03297                                 if (ebone->parent && (ebone->flag & BONE_CONNECTED)) {
03298                                         if (ebone->parent->flag & BONE_TIPSEL)
03299                                                 ebone->flag &= ~BONE_ROOTSEL;
03300                                 }
03301                         }
03302                 }
03303         }
03304         
03305         /* Duplicate the necessary bones */
03306         for (ebone = arm->edbo->first; ((ebone) && (ebone!=first)); ebone=ebone->next) {
03307                 if (EBONE_VISIBLE(arm, ebone)) {
03308                         /* we extrude per definition the tip */
03309                         do_extrude= 0;
03310                         if (ebone->flag & (BONE_TIPSEL|BONE_SELECTED))
03311                                 do_extrude= 1;
03312                         else if (ebone->flag & BONE_ROOTSEL) {
03313                                 /* but, a bone with parent deselected we do the root... */
03314                                 if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL));
03315                                 else do_extrude= 2;
03316                         }
03317                         
03318                         if (do_extrude) {
03319                                 /* we re-use code for mirror editing... */
03320                                 flipbone= NULL;
03321                                 if (arm->flag & ARM_MIRROR_EDIT) {
03322                                         flipbone= ED_armature_bone_get_mirrored(arm->edbo, ebone);
03323                                         if (flipbone) {
03324                                                 forked= 0;      // we extrude 2 different bones
03325                                                 if (flipbone->flag & (BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED))
03326                                                         /* don't want this bone to be selected... */
03327                                                         flipbone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
03328                                         }
03329                                         if ((flipbone==NULL) && (forked))
03330                                                 flipbone= ebone;
03331                                 }
03332                                 
03333                                 for (a=0; a<2; a++) {
03334                                         if (a==1) {
03335                                                 if (flipbone==NULL)
03336                                                         break;
03337                                                 else {
03338                                                         SWAP(EditBone *, flipbone, ebone);
03339                                                 }
03340                                         }
03341                                         
03342                                         totbone++;
03343                                         newbone = MEM_callocN(sizeof(EditBone), "extrudebone");
03344                                         
03345                                         if (do_extrude==1) {
03346                                                 copy_v3_v3(newbone->head, ebone->tail);
03347                                                 copy_v3_v3(newbone->tail, newbone->head);
03348                                                 newbone->parent = ebone;
03349                                                 
03350                                                 newbone->flag = ebone->flag & BONE_TIPSEL;      // copies it, in case mirrored bone
03351                                                 
03352                                                 if (newbone->parent) newbone->flag |= BONE_CONNECTED;
03353                                         }
03354                                         else {
03355                                                 copy_v3_v3(newbone->head, ebone->head);
03356                                                 copy_v3_v3(newbone->tail, ebone->head);
03357                                                 newbone->parent= ebone->parent;
03358                                                 
03359                                                 newbone->flag= BONE_TIPSEL;
03360                                                 
03361                                                 if (newbone->parent && (ebone->flag & BONE_CONNECTED)) {
03362                                                         newbone->flag |= BONE_CONNECTED;
03363                                                 }
03364                                         }
03365                                         
03366                                         newbone->weight= ebone->weight;
03367                                         newbone->dist= ebone->dist;
03368                                         newbone->xwidth= ebone->xwidth;
03369                                         newbone->zwidth= ebone->zwidth;
03370                                         newbone->ease1= ebone->ease1;
03371                                         newbone->ease2= ebone->ease2;
03372                                         newbone->rad_head= ebone->rad_tail;     // dont copy entire bone...
03373                                         newbone->rad_tail= ebone->rad_tail;
03374                                         newbone->segments= 1;
03375                                         newbone->layer= ebone->layer;
03376                                         
03377                                         BLI_strncpy (newbone->name, ebone->name, sizeof(newbone->name));
03378                                         
03379                                         if (flipbone && forked) {       // only set if mirror edit
03380                                                 if (strlen(newbone->name)<30) {
03381                                                         if (a==0) strcat(newbone->name, "_L");
03382                                                         else strcat(newbone->name, "_R");
03383                                                 }
03384                                         }
03385                                         unique_editbone_name(arm->edbo, newbone->name, NULL);
03386                                         
03387                                         /* Add the new bone to the list */
03388                                         BLI_addtail(arm->edbo, newbone);
03389                                         if (!first)
03390                                                 first = newbone;
03391                                         
03392                                         /* restore ebone if we were flipping */
03393                                         if (a==1 && flipbone) 
03394                                                 SWAP(EditBone *, flipbone, ebone);
03395                                 }
03396                         }
03397                         
03398                         /* Deselect the old bone */
03399                         ebone->flag &= ~(BONE_TIPSEL|BONE_SELECTED|BONE_ROOTSEL);
03400                 }               
03401         }
03402         /* if only one bone, make this one active */
03403         if (totbone==1 && first) arm->act_edbone= first;
03404 
03405         if (totbone==0) return OPERATOR_CANCELLED;
03406 
03407         /* Transform the endpoints */
03408         ED_armature_sync_selection(arm->edbo);
03409 
03410         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
03411 
03412         return OPERATOR_FINISHED;
03413 }
03414 
03415 void ARMATURE_OT_extrude(wmOperatorType *ot)
03416 {
03417         /* identifiers */
03418         ot->name= "Extrude";
03419         ot->idname= "ARMATURE_OT_extrude";
03420         ot->description= "Create new bones from the selected joints";
03421         
03422         /* api callbacks */
03423         ot->exec= armature_extrude_exec;
03424         ot->poll= ED_operator_editarmature;
03425         
03426         /* flags */
03427         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03428         
03429         /* props */
03430         RNA_def_boolean(ot->srna, "forked", 0, "Forked", "");
03431 }
03432 /* ********************** Bone Add ********************/
03433 
03434 /*op makes a new bone and returns it with its tip selected */
03435 
03436 static int armature_bone_primitive_add_exec(bContext *C, wmOperator *op) 
03437 {
03438         RegionView3D *rv3d= CTX_wm_region_view3d(C);
03439         Object *obedit = CTX_data_edit_object(C);
03440         EditBone *bone;
03441         float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
03442         char name[32];
03443         
03444         RNA_string_get(op->ptr, "name", name);
03445         
03446         copy_v3_v3(curs, give_cursor(CTX_data_scene(C),CTX_wm_view3d(C)));      
03447 
03448         /* Get inverse point for head and orientation for tail */
03449         invert_m4_m4(obedit->imat, obedit->obmat);
03450         mul_m4_v3(obedit->imat, curs);
03451 
03452         if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
03453                 copy_m3_m4(obmat, rv3d->viewmat);
03454         else unit_m3(obmat);
03455         
03456         copy_m3_m4(viewmat, obedit->obmat);
03457         mul_m3_m3m3(totmat, obmat, viewmat);
03458         invert_m3_m3(imat, totmat);
03459         
03460         ED_armature_deselect_all(obedit, 0);
03461         
03462         /*      Create a bone   */
03463         bone= ED_armature_edit_bone_add(obedit->data, name);
03464 
03465         copy_v3_v3(bone->head, curs);
03466         
03467         if(rv3d && (U.flag & USER_ADD_VIEWALIGNED))
03468                 add_v3_v3v3(bone->tail, bone->head, imat[1]);   // bone with unit length 1
03469         else
03470                 add_v3_v3v3(bone->tail, bone->head, imat[2]);   // bone with unit length 1, pointing up Z
03471 
03472         /* note, notifier might evolve */
03473         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
03474 
03475         return OPERATOR_FINISHED;
03476 }
03477 
03478 void ARMATURE_OT_bone_primitive_add(wmOperatorType *ot)
03479 {
03480         /* identifiers */
03481         ot->name= "Add Bone";
03482         ot->idname= "ARMATURE_OT_bone_primitive_add";
03483         ot->description= "Add a new bone located at the 3D-Cursor";
03484         
03485         /* api callbacks */
03486         ot->exec = armature_bone_primitive_add_exec;
03487         ot->poll = ED_operator_editarmature;
03488         
03489         /* flags */
03490         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03491         
03492         RNA_def_string(ot->srna, "name", "Bone", 32, "Name", "Name of the newly created bone");
03493         
03494 }
03495 
03496 
03497 /* ----------- */
03498 
03499 /* Subdivide Operators:
03500  * This group of operators all use the same 'exec' callback, but they are called
03501  * through several different operators - a combined menu (which just calls the exec in the 
03502  * appropriate ways), and two separate ones.
03503  */
03504 
03505 static int armature_subdivide_exec(bContext *C, wmOperator *op)
03506 {
03507         Object *obedit= CTX_data_edit_object(C);
03508         bArmature *arm= obedit->data;
03509         EditBone *newbone, *tbone;
03510         int numcuts, i;
03511         
03512         /* there may not be a number_cuts property defined (for 'simple' subdivide) */
03513         numcuts= RNA_int_get(op->ptr, "number_cuts");
03514         
03515         /* loop over all editable bones */
03516         // XXX the old code did this in reverse order though!
03517         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) 
03518         {
03519                 for (i=numcuts+1; i>1; i--) {
03520                         /* compute cut ratio first */
03521                         float cutratio= 1.0f / (float)i;
03522                         float cutratioI= 1.0f - cutratio;
03523                         
03524                         float val1[3];
03525                         float val2[3];
03526                         float val3[3];
03527                         
03528                         newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv");
03529                         *newbone = *ebone;
03530                         BLI_addtail(arm->edbo, newbone);
03531                         
03532                         /* calculate location of newbone->head */
03533                         copy_v3_v3(val1, ebone->head);
03534                         copy_v3_v3(val2, ebone->tail);
03535                         copy_v3_v3(val3, newbone->head);
03536                         
03537                         val3[0]= val1[0]*cutratio + val2[0]*cutratioI;
03538                         val3[1]= val1[1]*cutratio + val2[1]*cutratioI;
03539                         val3[2]= val1[2]*cutratio + val2[2]*cutratioI;
03540                         
03541                         copy_v3_v3(newbone->head, val3);
03542                         copy_v3_v3(newbone->tail, ebone->tail);
03543                         copy_v3_v3(ebone->tail, newbone->head);
03544                         
03545                         newbone->rad_head= 0.5f * (ebone->rad_head + ebone->rad_tail);
03546                         ebone->rad_tail= newbone->rad_head;
03547                         
03548                         newbone->flag |= BONE_CONNECTED;
03549                         
03550                         unique_editbone_name(arm->edbo, newbone->name, NULL);
03551                         
03552                         /* correct parent bones */
03553                         for (tbone = arm->edbo->first; tbone; tbone=tbone->next) {
03554                                 if (tbone->parent==ebone)
03555                                         tbone->parent= newbone;
03556                         }
03557                         newbone->parent= ebone;
03558                 }
03559         }
03560         CTX_DATA_END;
03561         
03562         /* note, notifier might evolve */
03563         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
03564         
03565         return OPERATOR_FINISHED;
03566 }
03567 
03568 void ARMATURE_OT_subdivide(wmOperatorType *ot)
03569 {
03570         /* identifiers */
03571         ot->name= "Subdivide Multi";
03572         ot->idname= "ARMATURE_OT_subdivide";
03573         ot->description= "Break selected bones into chains of smaller bones";
03574         
03575         /* api callbacks */
03576         ot->exec = armature_subdivide_exec;
03577         ot->poll = ED_operator_editarmature;
03578         
03579         /* flags */
03580         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03581         
03582         /* Properties */
03583         RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
03584 }
03585 
03586 /* ----------- */
03587 
03588 /* Switch Direction operator:
03589  * Currently, this does not use context loops, as context loops do not make it
03590  * easy to retrieve any hierarchial/chain relationships which are necessary for
03591  * this to be done easily.
03592  */
03593 
03594 static int armature_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) 
03595 {
03596         Object *ob= CTX_data_edit_object(C);
03597         bArmature *arm= (bArmature *)ob->data;
03598         ListBase chains = {NULL, NULL};
03599         LinkData *chain;
03600         
03601         /* get chains of bones (ends on chains) */
03602         chains_find_tips(arm->edbo, &chains);
03603         if (chains.first == NULL) return OPERATOR_CANCELLED;
03604 
03605         armature_tag_select_mirrored(arm);
03606 
03607         /* loop over chains, only considering selected and visible bones */
03608         for (chain= chains.first; chain; chain= chain->next) {
03609                 EditBone *ebo, *child=NULL, *parent=NULL;
03610                 
03611                 /* loop over bones in chain */
03612                 for (ebo= chain->data; ebo; ebo= parent) {
03613                         /* parent is this bone's original parent
03614                          *      - we store this, as the next bone that is checked is this one
03615                          *        but the value of ebo->parent may change here...
03616                          */
03617                         parent= ebo->parent;
03618                         
03619                         /* only if selected and editable */
03620                         if (EBONE_VISIBLE(arm, ebo) && EBONE_EDITABLE(ebo)) {                           
03621                                 /* swap head and tail coordinates */
03622                                 SWAP(float, ebo->head[0], ebo->tail[0]);
03623                                 SWAP(float, ebo->head[1], ebo->tail[1]);
03624                                 SWAP(float, ebo->head[2], ebo->tail[2]);
03625                                 
03626                                 /* do parent swapping:
03627                                  *      - use 'child' as new parent
03628                                  *      - connected flag is only set if points are coincidental
03629                                  */
03630                                 ebo->parent= child;
03631                                 if ((child) && equals_v3v3(ebo->head, child->tail))
03632                                         ebo->flag |= BONE_CONNECTED;
03633                                 else    
03634                                         ebo->flag &= ~BONE_CONNECTED;
03635                                 
03636                                 /* get next bones 
03637                                  *      - child will become the new parent of next bone
03638                                  */
03639                                 child= ebo;
03640                         }
03641                         else {
03642                                 /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it 
03643                                  * as it will be facing in opposite direction
03644                                  */
03645                                 if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
03646                                         ebo->parent= NULL;
03647                                         ebo->flag &= ~BONE_CONNECTED;
03648                                 }
03649                                 
03650                                 /* get next bones
03651                                  *      - child will become new parent of next bone (not swapping occurred, 
03652                                  *        so set to NULL to prevent infinite-loop)
03653                                  */
03654                                 child= NULL;
03655                         }
03656                 }
03657         }
03658         
03659         /* free chains */
03660         BLI_freelistN(&chains); 
03661 
03662         armature_tag_unselect(arm);
03663 
03664         /* note, notifier might evolve */
03665         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
03666         
03667         return OPERATOR_FINISHED;
03668 }
03669 
03670 void ARMATURE_OT_switch_direction(wmOperatorType *ot)
03671 {
03672         /* identifiers */
03673         ot->name= "Switch Direction";
03674         ot->idname= "ARMATURE_OT_switch_direction";
03675         ot->description= "Change the direction that a chain of bones points in (head <-> tail swap)";
03676         
03677         /* api callbacks */
03678         ot->exec = armature_switch_direction_exec;
03679         ot->poll = ED_operator_editarmature;
03680         
03681         /* flags */
03682         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03683 }
03684 /* ***************** Parenting *********************** */
03685 
03686 /* armature parenting options */
03687 #define ARM_PAR_CONNECT 1
03688 #define ARM_PAR_OFFSET  2
03689 
03690 /* check for null, before calling! */
03691 static void bone_connect_to_existing_parent(EditBone *bone)
03692 {
03693         bone->flag |= BONE_CONNECTED;
03694         copy_v3_v3(bone->head, bone->parent->tail);
03695         bone->rad_head = bone->parent->rad_tail;
03696 }
03697 
03698 static void bone_connect_to_new_parent(ListBase *edbo, EditBone *selbone, EditBone *actbone, short mode)
03699 {
03700         EditBone *ebone;
03701         float offset[3];
03702         
03703         if ((selbone->parent) && (selbone->flag & BONE_CONNECTED))
03704                 selbone->parent->flag &= ~(BONE_TIPSEL);
03705         
03706         /* make actbone the parent of selbone */
03707         selbone->parent= actbone;
03708         
03709         /* in actbone tree we cannot have a loop */
03710         for (ebone= actbone->parent; ebone; ebone= ebone->parent) {
03711                 if (ebone->parent==selbone) {
03712                         ebone->parent= NULL;
03713                         ebone->flag &= ~BONE_CONNECTED;
03714                 }
03715         }
03716         
03717         if (mode == ARM_PAR_CONNECT) {  
03718                 /* Connected: Child bones will be moved to the parent tip */
03719                 selbone->flag |= BONE_CONNECTED;
03720                 sub_v3_v3v3(offset, actbone->tail, selbone->head);
03721                 
03722                 copy_v3_v3(selbone->head, actbone->tail);
03723                 selbone->rad_head= actbone->rad_tail;
03724                 
03725                 add_v3_v3(selbone->tail, offset);
03726                 
03727                 /* offset for all its children */
03728                 for (ebone = edbo->first; ebone; ebone=ebone->next) {
03729                         EditBone *par;
03730                         
03731                         for (par= ebone->parent; par; par= par->parent) {
03732                                 if (par==selbone) {
03733                                         add_v3_v3(ebone->head, offset);
03734                                         add_v3_v3(ebone->tail, offset);
03735                                         break;
03736                                 }
03737                         }
03738                 }
03739         }
03740         else {
03741                 /* Offset: Child bones will retain their distance from the parent tip */
03742                 selbone->flag &= ~BONE_CONNECTED;
03743         }
03744 }
03745 
03746 static EnumPropertyItem prop_editarm_make_parent_types[] = {
03747         {ARM_PAR_CONNECT, "CONNECTED", 0, "Connected", ""},
03748         {ARM_PAR_OFFSET, "OFFSET", 0, "Keep Offset", ""},
03749         {0, NULL, 0, NULL, NULL}
03750 };
03751 
03752 static int armature_parent_set_exec(bContext *C, wmOperator *op) 
03753 {
03754         Object *ob= CTX_data_edit_object(C);
03755         bArmature *arm= (bArmature *)ob->data;
03756         EditBone *actbone = CTX_data_active_bone(C);
03757         EditBone *actmirb = NULL;
03758         short val = RNA_enum_get(op->ptr, "type");
03759         
03760         /* there must be an active bone */
03761         if (actbone == NULL) {
03762                 BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
03763                 return OPERATOR_CANCELLED;
03764         }
03765         else if (arm->flag & ARM_MIRROR_EDIT) {
03766                 /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
03767                  * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
03768                  *      (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
03769                  *      This is useful for arm-chains, for example parenting lower arm to upper arm
03770                  * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
03771                  *      then just use actbone. Useful when doing upper arm to spine.
03772                  */
03773                 actmirb= ED_armature_bone_get_mirrored(arm->edbo, actbone);
03774                 if (actmirb == NULL) 
03775                         actmirb= actbone;
03776         }
03777         
03778         /* if there is only 1 selected bone, we assume that that is the active bone, 
03779          * since a user will need to have clicked on a bone (thus selecting it) to make it active
03780          */
03781         if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) {
03782                 /* When only the active bone is selected, and it has a parent,
03783                  * connect it to the parent, as that is the only possible outcome. 
03784                  */
03785                 if (actbone->parent) {
03786                         bone_connect_to_existing_parent(actbone);
03787                         
03788                         if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
03789                                 bone_connect_to_existing_parent(actmirb);
03790                 }
03791         }
03792         else {
03793                 /* Parent 'selected' bones to the active one
03794                  * - the context iterator contains both selected bones and their mirrored copies,
03795                  *   so we assume that unselected bones are mirrored copies of some selected bone
03796                  * - since the active one (and/or its mirror) will also be selected, we also need 
03797                  *      to check that we are not trying to opearate on them, since such an operation 
03798                  *      would cause errors
03799                  */
03800                 
03801                 /* parent selected bones to the active one */
03802                 CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
03803                         if (ELEM(ebone, actbone, actmirb) == 0) {
03804                                 if (ebone->flag & BONE_SELECTED) 
03805                                         bone_connect_to_new_parent(arm->edbo, ebone, actbone, val);
03806                                 else
03807                                         bone_connect_to_new_parent(arm->edbo, ebone, actmirb, val);
03808                         }
03809                 }
03810                 CTX_DATA_END;
03811         }
03812         
03813 
03814         /* note, notifier might evolve */
03815         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
03816         
03817         return OPERATOR_FINISHED;
03818 }
03819 
03820 static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
03821 {
03822         EditBone *actbone = CTX_data_active_bone(C);
03823         uiPopupMenu *pup= uiPupMenuBegin(C, "Make Parent ", ICON_NONE);
03824         uiLayout *layout= uiPupMenuLayout(pup);
03825         int allchildbones = 0;
03826         
03827         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
03828                 if (ebone != actbone) {
03829                         if (ebone->parent != actbone) allchildbones= 1; 
03830                 }       
03831         }
03832         CTX_DATA_END;
03833 
03834         uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_CONNECT);
03835         
03836         /* ob becomes parent, make the associated menus */
03837         if (allchildbones)
03838                 uiItemEnumO(layout, "ARMATURE_OT_parent_set", NULL, 0, "type", ARM_PAR_OFFSET); 
03839                 
03840         uiPupMenuEnd(C, pup);
03841         
03842         return OPERATOR_CANCELLED;
03843 }
03844 
03845 void ARMATURE_OT_parent_set(wmOperatorType *ot)
03846 {
03847         /* identifiers */
03848         ot->name= "Make Parent";
03849         ot->idname= "ARMATURE_OT_parent_set";
03850         ot->description= "Set the active bone as the parent of the selected bones";
03851         
03852         /* api callbacks */
03853         ot->invoke = armature_parent_set_invoke;
03854         ot->exec = armature_parent_set_exec;
03855         ot->poll = ED_operator_editarmature;
03856         
03857         /* flags */
03858         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03859         
03860         RNA_def_enum(ot->srna, "type", prop_editarm_make_parent_types, 0, "ParentType", "Type of parenting");
03861 }
03862 
03863 static EnumPropertyItem prop_editarm_clear_parent_types[] = {
03864         {1, "CLEAR", 0, "Clear Parent", ""},
03865         {2, "DISCONNECT", 0, "Disconnect Bone", ""},
03866         {0, NULL, 0, NULL, NULL}
03867 };
03868 
03869 static void editbone_clear_parent(EditBone *ebone, int mode)
03870 {
03871         if (ebone->parent) {
03872                 /* for nice selection */
03873                 ebone->parent->flag &= ~(BONE_TIPSEL);
03874         }
03875         
03876         if (mode==1) ebone->parent= NULL;
03877         ebone->flag &= ~BONE_CONNECTED;
03878 }
03879 
03880 static int armature_parent_clear_exec(bContext *C, wmOperator *op) 
03881 {
03882         Object *ob= CTX_data_edit_object(C);
03883         bArmature *arm= (bArmature *)ob->data;
03884         int val = RNA_enum_get(op->ptr, "type");
03885                 
03886         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
03887                 editbone_clear_parent(ebone, val);
03888         }
03889         CTX_DATA_END;
03890         
03891         ED_armature_sync_selection(arm->edbo);
03892 
03893         /* note, notifier might evolve */
03894         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
03895         
03896         return OPERATOR_FINISHED;
03897 }
03898 
03899 void ARMATURE_OT_parent_clear(wmOperatorType *ot)
03900 {
03901         /* identifiers */
03902         ot->name= "Clear Parent";
03903         ot->idname= "ARMATURE_OT_parent_clear";
03904         ot->description= "Remove the parent-child relationship between selected bones and their parents";
03905         
03906         /* api callbacks */
03907         ot->invoke = WM_menu_invoke;
03908         ot->exec = armature_parent_clear_exec;
03909         ot->poll = ED_operator_editarmature;
03910         
03911         /* flags */
03912         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03913         
03914         ot->prop= RNA_def_enum(ot->srna, "type", prop_editarm_clear_parent_types, 0, "ClearType", "What way to clear parenting");
03915 }
03916 
03917 /* ****************  Selections  ******************/
03918 
03919 static int armature_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
03920 {
03921         /*      Set the flags */
03922         CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) {
03923                 /* ignore bone if selection can't change */
03924                 if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
03925                         /* select bone */
03926                         ebone->flag ^= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
03927                 }
03928         }
03929         CTX_DATA_END;   
03930 
03931         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
03932         
03933         return OPERATOR_FINISHED;
03934 }
03935 
03936 void ARMATURE_OT_select_inverse(wmOperatorType *ot)
03937 {
03938         /* identifiers */
03939         ot->name= "Select Inverse";
03940         ot->idname= "ARMATURE_OT_select_inverse";
03941         ot->description= "Flip the selection status of bones (selected -> unselected, unselected -> selected)";
03942         
03943         /* api callbacks */
03944         ot->exec= armature_select_inverse_exec;
03945         ot->poll= ED_operator_editarmature;
03946         
03947         /* flags */
03948         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
03949         
03950 }
03951 static int armature_de_select_all_exec(bContext *C, wmOperator *op)
03952 {
03953         int action = RNA_enum_get(op->ptr, "action");
03954 
03955         if (action == SEL_TOGGLE) {
03956                 action = SEL_SELECT;
03957                 /*      Determine if there are any selected bones
03958                 And therefore whether we are selecting or deselecting */
03959                 if (CTX_DATA_COUNT(C, selected_bones) > 0)
03960                         action = SEL_DESELECT;
03961         }
03962         
03963         /*      Set the flags */
03964         CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) {
03965                 /* ignore bone if selection can't change */
03966                 if ((ebone->flag & BONE_UNSELECTABLE) == 0) {
03967                         switch (action) {
03968                         case SEL_SELECT:
03969                                 ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
03970                                 if(ebone->parent)
03971                                         ebone->parent->flag |= (BONE_TIPSEL);
03972                                 break;
03973                         case SEL_DESELECT:
03974                                 ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
03975                                 break;
03976                         case SEL_INVERT:
03977                                 if (ebone->flag & BONE_SELECTED) {
03978                                         ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
03979                                 } 
03980                                 else {
03981                                         ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
03982                                         if(ebone->parent)
03983                                                 ebone->parent->flag |= (BONE_TIPSEL);
03984                                 }
03985                                 break;
03986                         }
03987                 }
03988         }
03989         CTX_DATA_END;   
03990 
03991         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
03992         
03993         return OPERATOR_FINISHED;
03994 }
03995 
03996 void ARMATURE_OT_select_all(wmOperatorType *ot)
03997 {
03998         /* identifiers */
03999         ot->name= "Select or Deselect All";
04000         ot->idname= "ARMATURE_OT_select_all";
04001         ot->description= "Toggle selection status of all bones";
04002         
04003         /* api callbacks */
04004         ot->exec= armature_de_select_all_exec;
04005         ot->poll= ED_operator_editarmature;
04006         
04007         /* flags */
04008         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
04009         
04010         WM_operator_properties_select_all(ot);
04011 }
04012 
04013 /* ********************* select hierarchy operator ************** */
04014 
04015 static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
04016 {
04017         Object *obedit= CTX_data_edit_object(C);
04018         Object *ob;
04019         bArmature *arm;
04020         EditBone *curbone, *pabone, *chbone;
04021         int direction = RNA_enum_get(op->ptr, "direction");
04022         int add_to_sel = RNA_boolean_get(op->ptr, "extend");
04023         
04024         ob= obedit;
04025         arm= (bArmature *)ob->data;
04026         
04027         for (curbone= arm->edbo->first; curbone; curbone= curbone->next) {
04028                 /* only work on bone if it is visible and its selection can change */
04029                 if (EBONE_VISIBLE(arm, curbone) && (curbone->flag & BONE_UNSELECTABLE)==0) {
04030                         if (curbone == arm->act_edbone) {
04031                                 if (direction == BONE_SELECT_PARENT) {
04032                                         if (curbone->parent == NULL) continue;
04033                                         else pabone = curbone->parent;
04034                                         
04035                                         if (EBONE_VISIBLE(arm, pabone)) {
04036                                                 pabone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04037                                                 arm->act_edbone= pabone;
04038                                                 if (pabone->parent)     pabone->parent->flag |= BONE_TIPSEL;
04039                                                 
04040                                                 if (!add_to_sel) curbone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04041                                                 break;
04042                                         }
04043                                         
04044                                 } 
04045                                 else { // BONE_SELECT_CHILD
04046                                         chbone = editbone_get_child(arm, curbone, 1);
04047                                         if (chbone == NULL) continue;
04048                                         
04049                                         if (EBONE_VISIBLE(arm, chbone) && (chbone->flag & BONE_UNSELECTABLE)==0) {
04050                                                 chbone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04051                                                 arm->act_edbone= chbone;
04052                                                 
04053                                                 if (!add_to_sel) {
04054                                                         curbone->flag &= ~(BONE_SELECTED|BONE_ROOTSEL);
04055                                                         if (curbone->parent) curbone->parent->flag &= ~BONE_TIPSEL;
04056                                                 }
04057                                                 break;
04058                                         }
04059                                 }
04060                         }
04061                 }
04062         }
04063         
04064         ED_armature_sync_selection(arm->edbo);
04065         
04066         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
04067         
04068         return OPERATOR_FINISHED;
04069 }
04070 
04071 void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
04072 {
04073         static EnumPropertyItem direction_items[]= {
04074         {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
04075         {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
04076         {0, NULL, 0, NULL, NULL}
04077         };
04078         
04079         /* identifiers */
04080         ot->name= "Select Hierarchy";
04081         ot->idname= "ARMATURE_OT_select_hierarchy";
04082         ot->description= "Select immediate parent/children of selected bones";
04083         
04084         /* api callbacks */
04085         ot->exec= armature_select_hierarchy_exec;
04086         ot->poll= ED_operator_editarmature;
04087         
04088         /* flags */
04089         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
04090 
04091         /* props */
04092         RNA_def_enum(ot->srna, "direction", direction_items,
04093                          BONE_SELECT_PARENT, "Direction", "");
04094         RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
04095 }
04096 
04097 /* ***************** EditBone Alignment ********************* */
04098 
04099 /* helper to fix a ebone position if its parent has moved due to alignment*/
04100 static void fix_connected_bone(EditBone *ebone)
04101 {
04102         float diff[3];
04103         
04104         if (!(ebone->parent) || !(ebone->flag & BONE_CONNECTED) || equals_v3v3(ebone->parent->tail, ebone->head))
04105                 return;
04106         
04107         /* if the parent has moved we translate child's head and tail accordingly*/
04108         sub_v3_v3v3(diff, ebone->parent->tail, ebone->head);
04109         add_v3_v3(ebone->head, diff);
04110         add_v3_v3(ebone->tail, diff);
04111         return;
04112 }
04113 
04114 /* helper to recursively find chains of connected bones starting at ebone and fix their position */
04115 static void fix_editbone_connected_children(ListBase *edbo, EditBone *ebone)
04116 {
04117         EditBone *selbone;
04118         
04119         for (selbone = edbo->first; selbone; selbone=selbone->next) {
04120                 if ((selbone->parent) && (selbone->parent == ebone) && (selbone->flag & BONE_CONNECTED)) {
04121                         fix_connected_bone(selbone);
04122                         fix_editbone_connected_children(edbo, selbone);
04123                 }
04124         }
04125         return;
04126 }                       
04127 
04128 static void bone_align_to_bone(ListBase *edbo, EditBone *selbone, EditBone *actbone)
04129 {
04130         float selboneaxis[3], actboneaxis[3], length;
04131 
04132         sub_v3_v3v3(actboneaxis, actbone->tail, actbone->head);
04133         normalize_v3(actboneaxis);
04134 
04135         sub_v3_v3v3(selboneaxis, selbone->tail, selbone->head);
04136         length =  len_v3(selboneaxis);
04137 
04138         mul_v3_fl(actboneaxis, length);
04139         add_v3_v3v3(selbone->tail, selbone->head, actboneaxis);
04140         selbone->roll = actbone->roll;
04141         
04142         /* if the bone being aligned has connected descendants they must be moved
04143         according to their parent new position, otherwise they would be left
04144         in an unconsistent state: connected but away from the parent*/
04145         fix_editbone_connected_children(edbo, selbone);
04146         return;
04147 }
04148 
04149 static int armature_align_bones_exec(bContext *C, wmOperator *op) 
04150 {
04151         Object *ob= CTX_data_edit_object(C);
04152         bArmature *arm= (bArmature *)ob->data;
04153         EditBone *actbone= CTX_data_active_bone(C);
04154         EditBone *actmirb= NULL;
04155         
04156         /* there must be an active bone */
04157         if (actbone == NULL) {
04158                 BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
04159                 return OPERATOR_CANCELLED;
04160         }
04161         else if (arm->flag & ARM_MIRROR_EDIT) {
04162                 /* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
04163                  * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
04164                  *      (i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
04165                  *      This is useful for arm-chains, for example parenting lower arm to upper arm
04166                  * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
04167                  *      then just use actbone. Useful when doing upper arm to spine.
04168                  */
04169                 actmirb= ED_armature_bone_get_mirrored(arm->edbo, actbone);
04170                 if (actmirb == NULL) 
04171                         actmirb= actbone;
04172         }
04173         
04174         /* if there is only 1 selected bone, we assume that that is the active bone, 
04175          * since a user will need to have clicked on a bone (thus selecting it) to make it active
04176          */
04177         if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) {
04178                 /* When only the active bone is selected, and it has a parent,
04179                  * align it to the parent, as that is the only possible outcome. 
04180                  */
04181                 if (actbone->parent) {
04182                         bone_align_to_bone(arm->edbo, actbone, actbone->parent);
04183                         
04184                         if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
04185                                 bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
04186                 }
04187         }
04188         else {
04189                 /* Align 'selected' bones to the active one
04190                  * - the context iterator contains both selected bones and their mirrored copies,
04191                  *   so we assume that unselected bones are mirrored copies of some selected bone
04192                  * - since the active one (and/or its mirror) will also be selected, we also need 
04193                  *      to check that we are not trying to opearate on them, since such an operation 
04194                  *      would cause errors
04195                  */
04196                 
04197                 /* align selected bones to the active one */
04198                 CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
04199                         if (ELEM(ebone, actbone, actmirb) == 0) {
04200                                 if (ebone->flag & BONE_SELECTED)
04201                                         bone_align_to_bone(arm->edbo, ebone, actbone);
04202                                 else
04203                                         bone_align_to_bone(arm->edbo, ebone, actmirb);
04204                         }
04205                 }
04206                 CTX_DATA_END;
04207         }
04208         
04209 
04210         /* note, notifier might evolve */
04211         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
04212         
04213         return OPERATOR_FINISHED;
04214 }
04215 
04216 void ARMATURE_OT_align(wmOperatorType *ot)
04217 {
04218         /* identifiers */
04219         ot->name= "Align Bones";
04220         ot->idname= "ARMATURE_OT_align";
04221         ot->description= "Align selected bones to the active bone (or to their parent)";
04222         
04223         /* api callbacks */
04224         ot->invoke = WM_operator_confirm;
04225         ot->exec = armature_align_bones_exec;
04226         ot->poll = ED_operator_editarmature;
04227         
04228         /* flags */
04229         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
04230 }
04231 
04232 /* ***************** Pose tools ********************* */
04233 
04234 // XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer 
04235 static int bone_looper(Object *ob, Bone *bone, void *data,
04236                                 int (*bone_func)(Object *, Bone *, void *)) 
04237 {
04238         /* We want to apply the function bone_func to every bone 
04239         * in an armature -- feed bone_looper the first bone and 
04240         * a pointer to the bone_func and watch it go!. The int count 
04241         * can be useful for counting bones with a certain property
04242         * (e.g. skinnable)
04243         */
04244         int count = 0;
04245         
04246         if (bone) {
04247                 /* only do bone_func if the bone is non null */
04248                 count += bone_func(ob, bone, data);
04249                 
04250                 /* try to execute bone_func for the first child */
04251                 count += bone_looper(ob, bone->childbase.first, data, bone_func);
04252                 
04253                 /* try to execute bone_func for the next bone at this
04254                         * depth of the recursion.
04255                         */
04256                 count += bone_looper(ob, bone->next, data, bone_func);
04257         }
04258         
04259         return count;
04260 }
04261 
04262 /* called from editview.c, for mode-less pose selection */
04263 /* assumes scene obact and basact is still on old situation */
04264 int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend)
04265 {
04266         Object *ob= base->object;
04267         Bone *nearBone;
04268         
04269         if (!ob || !ob->pose) return 0;
04270 
04271         nearBone= get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
04272         
04273         /* if the bone cannot be affected, don't do anything */
04274         if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
04275                 bArmature *arm= ob->data;
04276                 
04277                 /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */
04278                 if (!(extend) || (base != scene->basact)) {
04279                         ED_pose_deselectall(ob, 0);
04280                         nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04281                         arm->act_bone= nearBone;
04282                         
04283                                 // XXX old cruft! use notifiers instead
04284                         //select_actionchannel_by_name(ob->action, nearBone->name, 1);
04285                 }
04286                 else {
04287                         if (nearBone->flag & BONE_SELECTED) {
04288                                 /* if not active, we make it active */
04289                                 if(nearBone != arm->act_bone) {
04290                                         arm->act_bone= nearBone;
04291                                 }
04292                                 else {
04293                                         nearBone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04294                                         
04295                                                 // XXX old cruft! use notifiers instead
04296                                         //select_actionchannel_by_name(ob->action, nearBone->name, 0);
04297                                 }
04298                         }
04299                         else {
04300                                 nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04301                                 arm->act_bone= nearBone;
04302                                 
04303                                         // XXX old cruft! use notifiers instead
04304                                 //select_actionchannel_by_name(ob->action, nearBone->name, 1);
04305                         }
04306                 }
04307                 
04308                 /* in weightpaint we select the associated vertex group too */
04309                 if (OBACT && OBACT->mode & OB_MODE_WEIGHT_PAINT) {
04310                         if (nearBone == arm->act_bone) {
04311                                 ED_vgroup_select_by_name(OBACT, nearBone->name);
04312                                 DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA);
04313                         }
04314                 }
04315                 
04316         }
04317         
04318         return nearBone!=NULL;
04319 }
04320 
04321 /* test==0: deselect all
04322    test==1: swap select (apply to all the opposite of current situation) 
04323    test==2: only clear active tag
04324    test==3: swap select (no test / inverse selection status of all independently)
04325 */
04326 void ED_pose_deselectall (Object *ob, int test)
04327 {
04328         bArmature *arm= ob->data;
04329         bPoseChannel *pchan;
04330         int     selectmode= 0;
04331         
04332         /* we call this from outliner too */
04333         if (ELEM(NULL, ob, ob->pose)) return;
04334         
04335         /*      Determine if we're selecting or deselecting     */
04336         if (test==1) {
04337                 for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
04338                         if (PBONE_VISIBLE(arm, pchan->bone)) {
04339                                 if (pchan->bone->flag & BONE_SELECTED)
04340                                         break;
04341                         }
04342                 }
04343                 
04344                 if (pchan == NULL)
04345                         selectmode= 1;
04346         }
04347         else if (test == 2)
04348                 selectmode= 2;
04349         
04350         /*      Set the flags accordingly       */
04351         for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
04352                 /* ignore the pchan if it isn't visible or if its selection cannot be changed */
04353                 if ((pchan->bone->layer & arm->layer) && !(pchan->bone->flag & (BONE_HIDDEN_P|BONE_UNSELECTABLE))) {
04354                         if (test==3) {
04355                                 pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04356                         }
04357                         else {
04358                                 if (selectmode==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
04359                                 else if (selectmode==1) pchan->bone->flag |= BONE_SELECTED;
04360                         }
04361                 }
04362         }
04363 }
04364 
04365 static int bone_skinnable_cb(Object *ob, Bone *bone, void *datap)
04366 {
04367         /* Bones that are deforming
04368          * are regarded to be "skinnable" and are eligible for
04369          * auto-skinning.
04370          *
04371          * This function performs 2 functions:
04372          *
04373          *   a) It returns 1 if the bone is skinnable.
04374          *      If we loop over all bones with this 
04375          *      function, we can count the number of
04376          *      skinnable bones.
04377          *   b) If the pointer data is non null,
04378          *      it is treated like a handle to a
04379          *      bone pointer -- the bone pointer
04380          *      is set to point at this bone, and
04381          *      the pointer the handle points to
04382          *      is incremented to point to the
04383          *      next member of an array of pointers
04384          *      to bones. This way we can loop using
04385          *      this function to construct an array of
04386          *      pointers to bones that point to all
04387          *      skinnable bones.
04388          */
04389         Bone ***hbone;
04390         int a, segments;
04391         struct { Object *armob; void *list; int heat; } *data = datap;
04392 
04393         if(!(ob->mode & OB_MODE_WEIGHT_PAINT) || !(bone->flag & BONE_HIDDEN_P)) {
04394                 if (!(bone->flag & BONE_NO_DEFORM)) {
04395                         if (data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
04396                                 segments = bone->segments;
04397                         else
04398                                 segments = 1;
04399                         
04400                         if (data->list != NULL) {
04401                                 hbone = (Bone ***) &data->list;
04402                                 
04403                                 for (a=0; a<segments; a++) {
04404                                         **hbone = bone;
04405                                         ++*hbone;
04406                                 }
04407                         }
04408                         return segments;
04409                 }
04410         }
04411         return 0;
04412 }
04413 
04414 static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
04415 {
04416         /* This group creates a vertex group to ob that has the
04417           * same name as bone (provided the bone is skinnable). 
04418          * If such a vertex group aleady exist the routine exits.
04419           */
04420         if (!(bone->flag & BONE_NO_DEFORM)) {
04421                 if (!defgroup_find_name(ob,bone->name)) {
04422                         ED_vgroup_add_name(ob, bone->name);
04423                         return 1;
04424                 }
04425         }
04426         return 0;
04427 }
04428 
04429 static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap) 
04430 {
04431         /* Bones that are deforming
04432          * are regarded to be "skinnable" and are eligible for
04433          * auto-skinning.
04434          *
04435          * This function performs 2 functions:
04436          *
04437          *   a) If the bone is skinnable, it creates 
04438          *      a vertex group for ob that has
04439          *      the name of the skinnable bone
04440          *      (if one doesn't exist already).
04441          *   b) If the pointer data is non null,
04442          *      it is treated like a handle to a
04443          *      bDeformGroup pointer -- the 
04444          *      bDeformGroup pointer is set to point
04445          *      to the deform group with the bone's
04446          *      name, and the pointer the handle 
04447          *      points to is incremented to point to the
04448          *      next member of an array of pointers
04449          *      to bDeformGroups. This way we can loop using
04450          *      this function to construct an array of
04451          *      pointers to bDeformGroups, all with names
04452          *      of skinnable bones.
04453          */
04454         bDeformGroup ***hgroup, *defgroup= NULL;
04455         int a, segments;
04456         struct { Object *armob; void *list; int heat; } *data= datap;
04457         int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT);
04458         bArmature *arm= data->armob->data;
04459 
04460         if (!wpmode || !(bone->flag & BONE_HIDDEN_P)) {
04461            if (!(bone->flag & BONE_NO_DEFORM)) {
04462                         if (data->heat && data->armob->pose && get_pose_channel(data->armob->pose, bone->name))
04463                                 segments = bone->segments;
04464                         else
04465                                 segments = 1;
04466 
04467                         if(!wpmode || ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED)))
04468                                 if (!(defgroup = defgroup_find_name(ob, bone->name)))
04469                                         defgroup = ED_vgroup_add_name(ob, bone->name);
04470                         
04471                         if (data->list != NULL) {
04472                                 hgroup = (bDeformGroup ***) &data->list;
04473                                 
04474                                 for (a=0; a<segments; a++) {
04475                                         **hgroup = defgroup;
04476                                         ++*hgroup;
04477                                 }
04478                         }
04479                         return segments;
04480                 }
04481         }
04482         return 0;
04483 }
04484 
04485 static void add_vgroups__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
04486 {
04487         /* DerivedMesh mapFunc for getting final coords in weight paint mode */
04488 
04489         float (*verts)[3] = userData;
04490         copy_v3_v3(verts[index], co);
04491 }
04492 
04493 static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, float scale)
04494 {
04495         /* Create vertex group weights from envelopes */
04496 
04497         Bone *bone;
04498         bDeformGroup *dgroup;
04499         float distance;
04500         int i, iflip, j;
04501 
04502         /* for each vertex in the mesh */
04503         for (i=0; i < mesh->totvert; i++) {
04504                 iflip = (dgroupflip)? mesh_get_x_mirror_vert(ob, i): 0;
04505                 
04506                 /* for each skinnable bone */
04507                 for (j=0; j < numbones; ++j) {
04508                         if (!selected[j])
04509                                 continue;
04510                         
04511                         bone = bonelist[j];
04512                         dgroup = dgrouplist[j];
04513                         
04514                         /* store the distance-factor from the vertex to the bone */
04515                         distance = distfactor_to_bone (verts[i], root[j], tip[j],
04516                                 bone->rad_head * scale, bone->rad_tail * scale, bone->dist * scale);
04517                         
04518                         /* add the vert to the deform group if weight!=0.0 */
04519                         if (distance != 0.0f)
04520                                 ED_vgroup_vert_add (ob, dgroup, i, distance, WEIGHT_REPLACE);
04521                         else
04522                                 ED_vgroup_vert_remove (ob, dgroup, i);
04523                         
04524                         /* do same for mirror */
04525                         if (dgroupflip && dgroupflip[j] && iflip >= 0) {
04526                                 if (distance != 0.0f)
04527                                         ED_vgroup_vert_add (ob, dgroupflip[j], iflip, distance,
04528                                                 WEIGHT_REPLACE);
04529                                 else
04530                                         ED_vgroup_vert_remove (ob, dgroupflip[j], iflip);
04531                         }
04532                 }
04533         }
04534 }
04535 
04536 static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, Object *par, int heat, int mirror)
04537 {
04538         /* This functions implements the automatic computation of vertex group
04539          * weights, either through envelopes or using a heat equilibrium.
04540          *
04541          * This function can be called both when parenting a mesh to an armature,
04542          * or in weightpaint + posemode. In the latter case selection is taken
04543          * into account and vertex weights can be mirrored.
04544          *
04545          * The mesh vertex positions used are either the final deformed coords
04546          * from the derivedmesh in weightpaint mode, the final subsurf coords
04547          * when parenting, or simply the original mesh coords.
04548          */
04549 
04550         bArmature *arm= par->data;
04551         Bone **bonelist, *bone;
04552         bDeformGroup **dgrouplist, **dgroupflip;
04553         bDeformGroup *dgroup;
04554         bPoseChannel *pchan;
04555         Mesh *mesh;
04556         Mat4 *bbone = NULL;
04557         float (*root)[3], (*tip)[3], (*verts)[3];
04558         int *selected;
04559         int numbones, vertsfilled = 0, i, j, segments = 0;
04560         int wpmode = (ob->mode & OB_MODE_WEIGHT_PAINT);
04561         struct { Object *armob; void *list; int heat; } looper_data;
04562 
04563         looper_data.armob = par;
04564         looper_data.heat= heat;
04565         looper_data.list= NULL;
04566 
04567         /* count the number of skinnable bones */
04568         numbones = bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb);
04569         
04570         if (numbones == 0)
04571                 return;
04572         
04573         /* create an array of pointer to bones that are skinnable
04574          * and fill it with all of the skinnable bones */
04575         bonelist = MEM_callocN(numbones*sizeof(Bone *), "bonelist");
04576         looper_data.list= bonelist;
04577         bone_looper(ob, arm->bonebase.first, &looper_data, bone_skinnable_cb);
04578 
04579         /* create an array of pointers to the deform groups that
04580          * coorespond to the skinnable bones (creating them
04581          * as necessary. */
04582         dgrouplist = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgrouplist");
04583         dgroupflip = MEM_callocN(numbones*sizeof(bDeformGroup *), "dgroupflip");
04584 
04585         looper_data.list= dgrouplist;
04586         bone_looper(ob, arm->bonebase.first, &looper_data, dgroup_skinnable_cb);
04587 
04588         /* create an array of root and tip positions transformed into
04589          * global coords */
04590         root = MEM_callocN(numbones*sizeof(float)*3, "root");
04591         tip = MEM_callocN(numbones*sizeof(float)*3, "tip");
04592         selected = MEM_callocN(numbones*sizeof(int), "selected");
04593 
04594         for (j=0; j < numbones; ++j) {
04595                 bone = bonelist[j];
04596                 dgroup = dgrouplist[j];
04597                 
04598                 /* handle bbone */
04599                 if (heat) {
04600                         if (segments == 0) {
04601                                 segments = 1;
04602                                 bbone = NULL;
04603                                 
04604                                 if ((par->pose) && (pchan=get_pose_channel(par->pose, bone->name))) {
04605                                         if (bone->segments > 1) {
04606                                                 segments = bone->segments;
04607                                                 bbone = b_bone_spline_setup(pchan, 1);
04608                                         }
04609                                 }
04610                         }
04611                         
04612                         segments--;
04613                 }
04614                 
04615                 /* compute root and tip */
04616                 if (bbone) {
04617                         mul_v3_m4v3(root[j], bone->arm_mat, bbone[segments].mat[3]);
04618                         if ((segments+1) < bone->segments) {
04619                                 mul_v3_m4v3(tip[j], bone->arm_mat, bbone[segments+1].mat[3]);
04620                         }
04621                         else {
04622                                 copy_v3_v3(tip[j], bone->arm_tail);
04623                         }
04624                 }
04625                 else {
04626                         copy_v3_v3(root[j], bone->arm_head);
04627                         copy_v3_v3(tip[j], bone->arm_tail);
04628                 }
04629                 
04630                 mul_m4_v3(par->obmat, root[j]);
04631                 mul_m4_v3(par->obmat, tip[j]);
04632                 
04633                 /* set selected */
04634                 if (wpmode) {
04635                         if ((arm->layer & bone->layer) && (bone->flag & BONE_SELECTED))
04636                                 selected[j] = 1;
04637                 }
04638                 else
04639                         selected[j] = 1;
04640                 
04641                 /* find flipped group */
04642                 if (dgroup && mirror) {
04643                         char name[32];
04644 
04645                         // 0 = don't strip off number extensions
04646                         flip_side_name(name, dgroup->name, FALSE);
04647                         dgroupflip[j] = defgroup_find_name(ob, name);
04648                 }
04649         }
04650 
04651         /* create verts */
04652         mesh = (Mesh*)ob->data;
04653         verts = MEM_callocN(mesh->totvert*sizeof(*verts), "closestboneverts");
04654 
04655         if (wpmode) {
04656                 /* if in weight paint mode, use final verts from derivedmesh */
04657                 DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
04658                 
04659                 if (dm->foreachMappedVert) {
04660                         dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void*)verts);
04661                         vertsfilled = 1;
04662                 }
04663                 
04664                 dm->release(dm);
04665         }
04666         else if (modifiers_findByType(ob, eModifierType_Subsurf)) {
04667                 /* is subsurf on? Lets use the verts on the limit surface then.
04668                   * = same amount of vertices as mesh, but vertices  moved to the
04669                  * subsurfed position, like for 'optimal'. */
04670                 subsurf_calculate_limit_positions(mesh, verts);
04671                 vertsfilled = 1;
04672         }
04673 
04674         /* transform verts to global space */
04675         for (i=0; i < mesh->totvert; i++) {
04676                 if (!vertsfilled)
04677                         copy_v3_v3(verts[i], mesh->mvert[i].co);
04678                 mul_m4_v3(ob->obmat, verts[i]);
04679         }
04680 
04681         /* compute the weights based on gathered vertices and bones */
04682         if (heat) {
04683                 const char *error= NULL;
04684                 heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip,
04685                         root, tip, selected, &error);
04686                 
04687                 if(error) {
04688                         BKE_report(reports, RPT_WARNING, error);
04689                 }
04690         }
04691         else {
04692                 envelope_bone_weighting(ob, mesh, verts, numbones, bonelist, dgrouplist,
04693                         dgroupflip, root, tip, selected, mat4_to_scale(par->obmat));
04694         }
04695 
04696         /* only generated in some cases but can call anyway */
04697         mesh_octree_table(ob, NULL, NULL, 'e');
04698 
04699         /* free the memory allocated */
04700         MEM_freeN(bonelist);
04701         MEM_freeN(dgrouplist);
04702         MEM_freeN(dgroupflip);
04703         MEM_freeN(root);
04704         MEM_freeN(tip);
04705         MEM_freeN(selected);
04706         MEM_freeN(verts);
04707 }
04708 
04709 void create_vgroups_from_armature(ReportList *reports, Scene *scene, Object *ob, Object *par, int mode, int mirror)
04710 {
04711         /* Lets try to create some vertex groups 
04712          * based on the bones of the parent armature.
04713          */
04714         bArmature *arm= par->data;
04715 
04716         if(mode == ARM_GROUPS_NAME) {
04717                 /* Traverse the bone list, trying to create empty vertex 
04718                  * groups cooresponding to the bone.
04719                  */
04720                 bone_looper(ob, arm->bonebase.first, NULL, vgroup_add_unique_bone_cb);
04721 
04722                 if (ob->type == OB_MESH)
04723                         ED_vgroup_data_create(ob->data);
04724         }
04725         else if(mode == ARM_GROUPS_ENVELOPE || mode == ARM_GROUPS_AUTO) {
04726                 /* Traverse the bone list, trying to create vertex groups 
04727                  * that are populated with the vertices for which the
04728                  * bone is closest.
04729                  */
04730                 add_verts_to_dgroups(reports, scene, ob, par, (mode == ARM_GROUPS_AUTO), mirror);
04731         }
04732 } 
04733 /* ************* Clear Pose *****************************/
04734 
04735 /* clear scale of pose-channel */
04736 static void pchan_clear_scale(bPoseChannel *pchan)
04737 {
04738         if ((pchan->protectflag & OB_LOCK_SCALEX)==0)
04739                 pchan->size[0]= 1.0f;
04740         if ((pchan->protectflag & OB_LOCK_SCALEY)==0)
04741                 pchan->size[1]= 1.0f;
04742         if ((pchan->protectflag & OB_LOCK_SCALEZ)==0)
04743                 pchan->size[2]= 1.0f;
04744 }
04745 
04746 /* clear location of pose-channel */
04747 static void pchan_clear_loc(bPoseChannel *pchan)
04748 {
04749         if ((pchan->protectflag & OB_LOCK_LOCX)==0)
04750                 pchan->loc[0]= 0.0f;
04751         if ((pchan->protectflag & OB_LOCK_LOCY)==0)
04752                 pchan->loc[1]= 0.0f;
04753         if ((pchan->protectflag & OB_LOCK_LOCZ)==0)
04754                 pchan->loc[2]= 0.0f;
04755 }
04756 
04757 /* clear rotation of pose-channel */
04758 static void pchan_clear_rot(bPoseChannel *pchan)
04759 {
04760         if (pchan->protectflag & (OB_LOCK_ROTX|OB_LOCK_ROTY|OB_LOCK_ROTZ|OB_LOCK_ROTW)) {
04761                 /* check if convert to eulers for locking... */
04762                 if (pchan->protectflag & OB_LOCK_ROT4D) {
04763                         /* perform clamping on a component by component basis */
04764                         if (pchan->rotmode == ROT_MODE_AXISANGLE) {
04765                                 if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
04766                                         pchan->rotAngle= 0.0f;
04767                                 if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
04768                                         pchan->rotAxis[0]= 0.0f;
04769                                 if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
04770                                         pchan->rotAxis[1]= 0.0f;
04771                                 if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
04772                                         pchan->rotAxis[2]= 0.0f;
04773                                         
04774                                 /* check validity of axis - axis should never be 0,0,0 (if so, then we make it rotate about y) */
04775                                 if (IS_EQF(pchan->rotAxis[0], pchan->rotAxis[1]) && IS_EQF(pchan->rotAxis[1], pchan->rotAxis[2]))
04776                                         pchan->rotAxis[1] = 1.0f;
04777                         }
04778                         else if (pchan->rotmode == ROT_MODE_QUAT) {
04779                                 if ((pchan->protectflag & OB_LOCK_ROTW) == 0)
04780                                         pchan->quat[0]= 1.0f;
04781                                 if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
04782                                         pchan->quat[1]= 0.0f;
04783                                 if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
04784                                         pchan->quat[2]= 0.0f;
04785                                 if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
04786                                         pchan->quat[3]= 0.0f;
04787                         }
04788                         else {
04789                                 /* the flag may have been set for the other modes, so just ignore the extra flag... */
04790                                 if ((pchan->protectflag & OB_LOCK_ROTX) == 0)
04791                                         pchan->eul[0]= 0.0f;
04792                                 if ((pchan->protectflag & OB_LOCK_ROTY) == 0)
04793                                         pchan->eul[1]= 0.0f;
04794                                 if ((pchan->protectflag & OB_LOCK_ROTZ) == 0)
04795                                         pchan->eul[2]= 0.0f;
04796                         }
04797                 }
04798                 else {
04799                         /* perform clamping using euler form (3-components) */
04800                         float eul[3], oldeul[3], quat1[4] = {0};
04801                         float qlen = 0.0f;
04802                         
04803                         if (pchan->rotmode == ROT_MODE_QUAT) {
04804                                 qlen= normalize_qt_qt(quat1, pchan->quat);
04805                                 quat_to_eul(oldeul, quat1);
04806                         }
04807                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
04808                                 axis_angle_to_eulO( oldeul, EULER_ORDER_DEFAULT,pchan->rotAxis, pchan->rotAngle);
04809                         }
04810                         else {
04811                                 copy_v3_v3(oldeul, pchan->eul);
04812                         }
04813                         
04814                         eul[0]= eul[1]= eul[2]= 0.0f;
04815                         
04816                         if (pchan->protectflag & OB_LOCK_ROTX)
04817                                 eul[0]= oldeul[0];
04818                         if (pchan->protectflag & OB_LOCK_ROTY)
04819                                 eul[1]= oldeul[1];
04820                         if (pchan->protectflag & OB_LOCK_ROTZ)
04821                                 eul[2]= oldeul[2];
04822                         
04823                         if (pchan->rotmode == ROT_MODE_QUAT) {
04824                                 eul_to_quat(pchan->quat, eul);
04825                                 
04826                                 /* restore original quat size */
04827                                 mul_qt_fl(pchan->quat, qlen);
04828                                 
04829                                 /* quaternions flip w sign to accumulate rotations correctly */
04830                                 if ((quat1[0]<0.0f && pchan->quat[0]>0.0f) || (quat1[0]>0.0f && pchan->quat[0]<0.0f)) {
04831                                         mul_qt_fl(pchan->quat, -1.0f);
04832                                 }
04833                         }
04834                         else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
04835                                 eulO_to_axis_angle( pchan->rotAxis, &pchan->rotAngle,eul, EULER_ORDER_DEFAULT);
04836                         }
04837                         else {
04838                                 copy_v3_v3(pchan->eul, eul);
04839                         }
04840                 }
04841         }                                               // Duplicated in source/blender/editors/object/object_transform.c
04842         else { 
04843                 if (pchan->rotmode == ROT_MODE_QUAT) {
04844                         unit_qt(pchan->quat);
04845                 }
04846                 else if (pchan->rotmode == ROT_MODE_AXISANGLE) {
04847                         /* by default, make rotation of 0 radians around y-axis (roll) */
04848                         unit_axis_angle(pchan->rotAxis, &pchan->rotAngle);
04849                 }
04850                 else {
04851                         zero_v3(pchan->eul);
04852                 }
04853         }
04854 }
04855 
04856 /* clear loc/rot/scale of pose-channel */
04857 static void pchan_clear_transforms(bPoseChannel *pchan)
04858 {
04859         pchan_clear_loc(pchan);
04860         pchan_clear_rot(pchan);
04861         pchan_clear_scale(pchan);
04862 }
04863 
04864 /* --------------- */
04865 
04866 /* generic exec for clear-pose operators */
04867 static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, 
04868                 void (*clear_func)(bPoseChannel*), const char default_ksName[])
04869 {
04870         Scene *scene= CTX_data_scene(C);
04871         Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
04872         short autokey = 0;
04873         
04874         /* sanity checks */
04875         if ELEM(NULL, clear_func, default_ksName) {
04876                 BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name");
04877                 return OPERATOR_CANCELLED;
04878         }
04879         
04880         /* only clear relevant transforms for selected bones */
04881         CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pose_bones) 
04882         {
04883                 /* run provided clearing function */
04884                 clear_func(pchan);
04885                 
04886                 /* do auto-keyframing as appropriate */
04887                 if (autokeyframe_cfra_can_key(scene, &ob->id)) {
04888                         /* clear any unkeyed tags */
04889                         if (pchan->bone)
04890                                 pchan->bone->flag &= ~BONE_UNKEYED;
04891                                 
04892                         /* tag for autokeying later */
04893                         autokey = 1;
04894                 }
04895                 else {
04896                         /* add unkeyed tags */
04897                         if (pchan->bone)
04898                                 pchan->bone->flag |= BONE_UNKEYED;
04899                 }
04900         }
04901         CTX_DATA_END;
04902         
04903         /* perform autokeying on the bones if needed */
04904         if (autokey) {
04905                 /* get KeyingSet to use */
04906                 KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName);
04907                 
04908                 /* insert keyframes */
04909                 ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
04910                 
04911                 /* now recalculate paths */
04912                 if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS))
04913                         ED_pose_recalculate_paths(scene, ob);
04914         }
04915         
04916         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
04917 
04918         /* note, notifier might evolve */
04919         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
04920         
04921         return OPERATOR_FINISHED;
04922 }
04923 
04924 /* --------------- */
04925 
04926 static int pose_clear_scale_exec(bContext *C, wmOperator *op) 
04927 {
04928         return pose_clear_transform_generic_exec(C, op, pchan_clear_scale, "Scaling");
04929 }
04930 
04931 void POSE_OT_scale_clear(wmOperatorType *ot)
04932 {
04933         /* identifiers */
04934         ot->name= "Clear Pose Scale";
04935         ot->idname= "POSE_OT_scale_clear";
04936         ot->description = "Reset scaling of selected bones to their default values";
04937         
04938         /* api callbacks */
04939         ot->exec = pose_clear_scale_exec;
04940         ot->poll = ED_operator_posemode;
04941         
04942         /* flags */
04943         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
04944 }
04945 
04946 
04947 static int pose_clear_rot_exec(bContext *C, wmOperator *op) 
04948 {
04949         return pose_clear_transform_generic_exec(C, op, pchan_clear_rot, "Rotation");
04950 }
04951 
04952 void POSE_OT_rot_clear(wmOperatorType *ot)
04953 {
04954         /* identifiers */
04955         ot->name= "Clear Pose Rotation";
04956         ot->idname= "POSE_OT_rot_clear";
04957         ot->description = "Reset rotations of selected bones to their default values";
04958         
04959         /* api callbacks */
04960         ot->exec = pose_clear_rot_exec;
04961         ot->poll = ED_operator_posemode;
04962         
04963         /* flags */
04964         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
04965 }
04966 
04967 
04968 static int pose_clear_loc_exec(bContext *C, wmOperator *op) 
04969 {
04970         return pose_clear_transform_generic_exec(C, op, pchan_clear_loc, "Location");
04971 }
04972 
04973 void POSE_OT_loc_clear(wmOperatorType *ot)
04974 {
04975         /* identifiers */
04976         ot->name= "Clear Pose Location";
04977         ot->idname= "POSE_OT_loc_clear";
04978         ot->description = "Reset locations of selected bones to their default values";
04979         
04980         /* api callbacks */
04981         ot->exec = pose_clear_loc_exec;
04982         ot->poll = ED_operator_posemode;
04983         
04984         /* flags */
04985         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
04986 }
04987 
04988 
04989 static int pose_clear_transforms_exec(bContext *C, wmOperator *op) 
04990 {
04991         return pose_clear_transform_generic_exec(C, op, pchan_clear_transforms, "LocRotScale");
04992 }
04993 
04994 void POSE_OT_transforms_clear(wmOperatorType *ot)
04995 {
04996         /* identifiers */
04997         ot->name= "Clear Pose Transforms";
04998         ot->idname= "POSE_OT_transforms_clear";
04999         ot->description = "Reset location, rotation, and scaling of selected bones to their default values";
05000         
05001         /* api callbacks */
05002         ot->exec = pose_clear_transforms_exec;
05003         ot->poll = ED_operator_posemode;
05004         
05005         /* flags */
05006         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05007 }
05008 
05009 /* ***************** selections ********************** */
05010 
05011 static int pose_select_inverse_exec(bContext *C, wmOperator *UNUSED(op))
05012 {
05013         
05014         /*      Set the flags */
05015         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) 
05016         {
05017                 if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
05018                         pchan->bone->flag ^= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
05019                 }
05020         }       
05021         CTX_DATA_END;
05022         
05023         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
05024         
05025         return OPERATOR_FINISHED;
05026 }
05027 
05028 void POSE_OT_select_inverse(wmOperatorType *ot)
05029 {
05030         /* identifiers */
05031         ot->name= "Select Inverse";
05032         ot->idname= "POSE_OT_select_inverse";
05033         ot->description= "Flip the selection status of bones (selected -> unselected, unselected -> selected)";
05034         
05035         /* api callbacks */
05036         ot->exec= pose_select_inverse_exec;
05037         ot->poll= ED_operator_posemode;
05038         
05039         /* flags */
05040         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05041         
05042 }
05043 static int pose_de_select_all_exec(bContext *C, wmOperator *op)
05044 {
05045         int action = RNA_enum_get(op->ptr, "action");
05046 
05047         if (action == SEL_TOGGLE) {
05048                 action= CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT;
05049         }
05050         
05051         /*      Set the flags */
05052         CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) {
05053                 /* select pchan only if selectable, but deselect works always */
05054                 switch (action) {
05055                 case SEL_SELECT:
05056                         if ((pchan->bone->flag & BONE_UNSELECTABLE)==0)
05057                                 pchan->bone->flag |= BONE_SELECTED;
05058                         break;
05059                 case SEL_DESELECT:
05060                         pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
05061                         break;
05062                 case SEL_INVERT:
05063                         if (pchan->bone->flag & BONE_SELECTED) {
05064                                 pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
05065                         } 
05066                         else if ((pchan->bone->flag & BONE_UNSELECTABLE)==0) {
05067                                         pchan->bone->flag |= BONE_SELECTED;
05068                         }
05069                         break;
05070                 }
05071         }
05072         CTX_DATA_END;
05073 
05074         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
05075         
05076         return OPERATOR_FINISHED;
05077 }
05078 
05079 void POSE_OT_select_all(wmOperatorType *ot)
05080 {
05081         /* identifiers */
05082         ot->name= "Select or Deselect All";
05083         ot->idname= "POSE_OT_select_all";
05084         ot->description= "Toggle selection status of all bones";
05085         
05086         /* api callbacks */
05087         ot->exec= pose_de_select_all_exec;
05088         ot->poll= ED_operator_posemode;
05089         
05090         /* flags */
05091         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05092         
05093         WM_operator_properties_select_all(ot);
05094 }
05095 
05096 static int pose_select_parent_exec(bContext *C, wmOperator *UNUSED(op))
05097 {
05098         Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
05099         bPoseChannel *pchan,*parent;
05100 
05101         /*      Determine if there is an active bone */
05102         pchan=CTX_data_active_pose_bone(C);
05103         if (pchan) {
05104                 bArmature *arm= ob->data;
05105                 parent=pchan->parent;
05106                 if ((parent) && !(parent->bone->flag & (BONE_HIDDEN_P|BONE_UNSELECTABLE))) {
05107                         parent->bone->flag |= BONE_SELECTED;
05108                         arm->act_bone= parent->bone;
05109                 }
05110                 else {
05111                         return OPERATOR_CANCELLED;
05112                 }
05113         }
05114         else {
05115                 return OPERATOR_CANCELLED;
05116         }
05117 
05118         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
05119         
05120         return OPERATOR_FINISHED;
05121 }
05122 
05123 void POSE_OT_select_parent(wmOperatorType *ot)
05124 {
05125         /* identifiers */
05126         ot->name= "Select Parent Bone";
05127         ot->idname= "POSE_OT_select_parent";
05128         ot->description= "Select bones that are parents of the currently selected bones";
05129 
05130         /* api callbacks */
05131         ot->exec= pose_select_parent_exec;
05132         ot->poll= ED_operator_posemode;
05133 
05134         /* flags */
05135         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05136         
05137 }
05138 
05139 /* ************* hide/unhide pose bones ******************* */
05140 
05141 static int hide_selected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
05142 {
05143         bArmature *arm= ob->data;
05144         
05145         if (arm->layer & bone->layer) {
05146                 if (bone->flag & BONE_SELECTED) {
05147                         bone->flag |= BONE_HIDDEN_P;
05148                         bone->flag &= ~BONE_SELECTED;
05149                         if(arm->act_bone==bone)
05150                                 arm->act_bone= NULL;
05151                 }
05152         }
05153         return 0;
05154 }
05155 
05156 static int hide_unselected_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
05157 {
05158         bArmature *arm= ob->data;
05159         
05160         if (arm->layer & bone->layer) {
05161                 // hrm... typo here?
05162                 if ((bone->flag & BONE_SELECTED)==0) {
05163                         bone->flag |= BONE_HIDDEN_P;
05164                         if(arm->act_bone==bone)
05165                                 arm->act_bone= NULL;
05166                 }
05167         }
05168         return 0;
05169 }
05170 
05171 /* active object is armature in posemode, poll checked */
05172 static int pose_hide_exec(bContext *C, wmOperator *op) 
05173 {
05174         Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
05175         bArmature *arm= ob->data;
05176 
05177         if(RNA_boolean_get(op->ptr, "unselected"))
05178            bone_looper(ob, arm->bonebase.first, NULL, hide_unselected_pose_bone_cb);
05179         else
05180            bone_looper(ob, arm->bonebase.first, NULL, hide_selected_pose_bone_cb);
05181         
05182         /* note, notifier might evolve */
05183         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
05184         
05185         return OPERATOR_FINISHED;
05186 }
05187 
05188 void POSE_OT_hide(wmOperatorType *ot)
05189 {
05190         /* identifiers */
05191         ot->name= "Hide Selected";
05192         ot->idname= "POSE_OT_hide";
05193         ot->description= "Tag selected bones to not be visible in Pose Mode";
05194         
05195         /* api callbacks */
05196         ot->exec= pose_hide_exec;
05197         ot->poll= ED_operator_posemode;
05198         
05199         /* flags */
05200         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05201         
05202         /* props */
05203         RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "");
05204 }
05205 
05206 static int show_pose_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr)) 
05207 {
05208         bArmature *arm= ob->data;
05209         
05210         if (arm->layer & bone->layer) {
05211                 if (bone->flag & BONE_HIDDEN_P) {
05212                         bone->flag &= ~BONE_HIDDEN_P;
05213                         bone->flag |= BONE_SELECTED;
05214                 }
05215         }
05216         
05217         return 0;
05218 }
05219 
05220 /* active object is armature in posemode, poll checked */
05221 static int pose_reveal_exec(bContext *C, wmOperator *UNUSED(op)) 
05222 {
05223         Object *ob= ED_object_pose_armature(CTX_data_active_object(C));
05224         bArmature *arm= ob->data;
05225         
05226         bone_looper(ob, arm->bonebase.first, NULL, show_pose_bone_cb);
05227         
05228         /* note, notifier might evolve */
05229         WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, ob);
05230 
05231         return OPERATOR_FINISHED;
05232 }
05233 
05234 void POSE_OT_reveal(wmOperatorType *ot)
05235 {
05236         /* identifiers */
05237         ot->name= "Reveal Selected";
05238         ot->idname= "POSE_OT_reveal";
05239         ot->description= "Unhide all bones that have been tagged to be hidden in Pose Mode";
05240         
05241         /* api callbacks */
05242         ot->exec= pose_reveal_exec;
05243         ot->poll= ED_operator_posemode;
05244         
05245         /* flags */
05246         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05247 }
05248 
05249 /* ************* RENAMING DISASTERS ************ */
05250 
05251 static int bone_unique_check(void *arg, const char *name)
05252 {
05253         return get_named_bone((bArmature *)arg, name) != NULL;
05254 }
05255 
05256 static void unique_bone_name(bArmature *arm, char *name)
05257 {
05258         BLI_uniquename_cb(bone_unique_check, (void *)arm, "Bone", '.', name, sizeof(((Bone *)NULL)->name));
05259 }
05260 
05261 /* helper call for armature_bone_rename */
05262 static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldname, char *newname)
05263 {
05264         bConstraint *curcon;
05265         bConstraintTarget *ct;
05266         
05267         for (curcon = conlist->first; curcon; curcon=curcon->next) {
05268                 bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
05269                 ListBase targets = {NULL, NULL};
05270                 
05271                 if (cti && cti->get_constraint_targets) {
05272                         cti->get_constraint_targets(curcon, &targets);
05273                         
05274                         for (ct= targets.first; ct; ct= ct->next) {
05275                                 if (ct->tar == ob) {
05276                                         if (!strcmp(ct->subtarget, oldname) )
05277                                                 BLI_strncpy(ct->subtarget, newname, MAXBONENAME);
05278                                 }
05279                         }
05280                         
05281                         if (cti->flush_constraint_targets)
05282                                 cti->flush_constraint_targets(curcon, &targets, 0);
05283                 }       
05284         }
05285 }
05286 
05287 /* called by UI for renaming a bone */
05288 /* warning: make sure the original bone was not renamed yet! */
05289 /* seems messy, but thats what you get with not using pointers but channel names :) */
05290 void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
05291 {
05292         Object *ob;
05293         char newname[MAXBONENAME];
05294         char oldname[MAXBONENAME];
05295         
05296         /* names better differ! */
05297         if(strncmp(oldnamep, newnamep, MAXBONENAME)) {
05298                 
05299                 /* we alter newname string... so make copy */
05300                 BLI_strncpy(newname, newnamep, MAXBONENAME);
05301                 /* we use oldname for search... so make copy */
05302                 BLI_strncpy(oldname, oldnamep, MAXBONENAME);
05303                 
05304                 /* now check if we're in editmode, we need to find the unique name */
05305                 if (arm->edbo) {
05306                         EditBone *eBone= editbone_name_exists(arm->edbo, oldname);
05307                         
05308                         if (eBone) {
05309                                 unique_editbone_name(arm->edbo, newname, NULL);
05310                                 BLI_strncpy(eBone->name, newname, MAXBONENAME);
05311                         }
05312                         else return;
05313                 }
05314                 else {
05315                         Bone *bone= get_named_bone(arm, oldname);
05316                         
05317                         if (bone) {
05318                                 unique_bone_name(arm, newname);
05319                                 BLI_strncpy(bone->name, newname, MAXBONENAME);
05320                         }
05321                         else return;
05322                 }
05323                 
05324                 /* do entire dbase - objects */
05325                 for (ob= G.main->object.first; ob; ob= ob->id.next) {
05326                         ModifierData *md;
05327                         
05328                         /* we have the object using the armature */
05329                         if (arm==ob->data) {
05330                                 Object *cob;
05331                                 
05332                                 /* Rename the pose channel, if it exists */
05333                                 if (ob->pose) {
05334                                         bPoseChannel *pchan = get_pose_channel(ob->pose, oldname);
05335                                         if (pchan) {
05336                                                 BLI_strncpy(pchan->name, newname, MAXBONENAME);
05337                                                 
05338                                                 if (ob->pose->chanhash) {
05339                                                         GHash *gh = ob->pose->chanhash;
05340                                                         
05341                                                         /* remove the old hash entry, and replace with the new name */
05342                                                         BLI_ghash_remove(gh, oldname, NULL, NULL);
05343                                                         BLI_ghash_insert(gh, pchan->name, pchan);
05344                                                 }
05345                                         }
05346                                 }
05347                                 
05348                                 /* Update any object constraints to use the new bone name */
05349                                 for (cob= G.main->object.first; cob; cob= cob->id.next) {
05350                                         if (cob->constraints.first)
05351                                                 constraint_bone_name_fix(ob, &cob->constraints, oldname, newname);
05352                                         if (cob->pose) {
05353                                                 bPoseChannel *pchan;
05354                                                 for (pchan = cob->pose->chanbase.first; pchan; pchan=pchan->next) {
05355                                                         constraint_bone_name_fix(ob, &pchan->constraints, oldname, newname);
05356                                                 }
05357                                         }
05358                                 }
05359                         }
05360                                         
05361                         /* See if an object is parented to this armature */
05362                         if (ob->parent && (ob->parent->data == arm)) {
05363                                 if (ob->partype==PARBONE) {
05364                                         /* bone name in object */
05365                                         if (!strcmp(ob->parsubstr, oldname))
05366                                                 BLI_strncpy(ob->parsubstr, newname, MAXBONENAME);
05367                                 }
05368                         }
05369                         
05370                         if (modifiers_usesArmature(ob, arm)) { 
05371                                 bDeformGroup *dg= defgroup_find_name(ob, oldname);
05372                                 if(dg) {
05373                                         BLI_strncpy(dg->name, newname, MAXBONENAME);
05374                                 }
05375                         }
05376                         
05377                         /* fix modifiers that might be using this name */
05378                         for (md= ob->modifiers.first; md; md= md->next) {
05379                                 if (md->type == eModifierType_Hook) {
05380                                         HookModifierData *hmd = (HookModifierData *)md;
05381                                         
05382                                         /* uses armature, so may use the affected bone name */
05383                                         if (hmd->object && (hmd->object->data == arm)) {
05384                                                 if (!strcmp(hmd->subtarget, oldname))
05385                                                         BLI_strncpy(hmd->subtarget, newname, MAXBONENAME);
05386                                         }
05387                                 }
05388                         }
05389                         
05390                         /* Fix animation data attached to this object */
05391                         // TODO: should we be using the database wide version instead (since drivers may break)
05392                         if (ob->adt) {
05393                                 /* posechannels only... */
05394                                 BKE_animdata_fix_paths_rename(&ob->id, ob->adt, "pose.bones", oldname, newname, 0, 0, 1);
05395                         }
05396                 }
05397 
05398                 {
05399                         /* correct view locking */
05400                         bScreen *screen;
05401                         for(screen= G.main->screen.first; screen; screen= screen->id.next) {
05402                                 ScrArea *sa;
05403                                 /* add regions */
05404                                 for(sa= screen->areabase.first; sa; sa= sa->next) {
05405                                         SpaceLink *sl= sa->spacedata.first;
05406                                         if(sl->spacetype == SPACE_VIEW3D) {
05407                                                 View3D *v3d= (View3D *)sl;
05408                                                 if(v3d->ob_centre && v3d->ob_centre->data == arm) {
05409                                                         if (!strcmp(v3d->ob_centre_bone, oldname)) {
05410                                                                 BLI_strncpy(v3d->ob_centre_bone, newname, MAXBONENAME);
05411                                                         }
05412                                                 }
05413                                         }
05414                                 }
05415                         }
05416                 }
05417         }
05418 }
05419 
05420 
05421 static int armature_flip_names_exec (bContext *C, wmOperator *UNUSED(op))
05422 {
05423         Object *ob= CTX_data_edit_object(C);
05424         bArmature *arm;
05425         char newname[32];
05426         
05427         /* paranoia checks */
05428         if (ELEM(NULL, ob, ob->pose)) 
05429                 return OPERATOR_CANCELLED;
05430         arm= ob->data;
05431         
05432         /* loop through selected bones, auto-naming them */
05433         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
05434         {
05435                 flip_side_name(newname, ebone->name, TRUE); // 1 = do strip off number extensions
05436                 ED_armature_bone_rename(arm, ebone->name, newname);
05437         }
05438         CTX_DATA_END;
05439         
05440         /* since we renamed stuff... */
05441         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
05442 
05443         /* note, notifier might evolve */
05444         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
05445         
05446         return OPERATOR_FINISHED;
05447 }
05448 
05449 void ARMATURE_OT_flip_names (wmOperatorType *ot)
05450 {
05451         /* identifiers */
05452         ot->name= "Flip Names";
05453         ot->idname= "ARMATURE_OT_flip_names";
05454         ot->description= "Flips (and corrects) the axis suffixes of the names of selected bones";
05455         
05456         /* api callbacks */
05457         ot->exec= armature_flip_names_exec;
05458         ot->poll= ED_operator_editarmature;
05459         
05460         /* flags */
05461         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05462 }
05463 
05464 
05465 static int armature_autoside_names_exec (bContext *C, wmOperator *op)
05466 {
05467         Object *ob= CTX_data_edit_object(C);
05468         bArmature *arm;
05469         char newname[32];
05470         short axis= RNA_enum_get(op->ptr, "type");
05471         
05472         /* paranoia checks */
05473         if (ELEM(NULL, ob, ob->pose)) 
05474                 return OPERATOR_CANCELLED;
05475         arm= ob->data;
05476         
05477         /* loop through selected bones, auto-naming them */
05478         CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones)
05479         {
05480                 BLI_strncpy(newname, ebone->name, sizeof(newname));
05481                 if(bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis]))
05482                         ED_armature_bone_rename(arm, ebone->name, newname);
05483         }
05484         CTX_DATA_END;
05485         
05486         /* since we renamed stuff... */
05487         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
05488 
05489         /* note, notifier might evolve */
05490         WM_event_add_notifier(C, NC_OBJECT|ND_POSE, ob);
05491         
05492         return OPERATOR_FINISHED;
05493 }
05494 
05495 void ARMATURE_OT_autoside_names (wmOperatorType *ot)
05496 {
05497         static EnumPropertyItem axis_items[]= {
05498                  {0, "XAXIS", 0, "X-Axis", "Left/Right"},
05499                 {1, "YAXIS", 0, "Y-Axis", "Front/Back"},
05500                 {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"},
05501                 {0, NULL, 0, NULL, NULL}};
05502         
05503         /* identifiers */
05504         ot->name= "AutoName by Axis";
05505         ot->idname= "ARMATURE_OT_autoside_names";
05506         ot->description= "Automatically renames the selected bones according to which side of the target axis they fall on";
05507         
05508         /* api callbacks */
05509         ot->invoke= WM_menu_invoke;
05510         ot->exec= armature_autoside_names_exec;
05511         ot->poll= ED_operator_editarmature;
05512         
05513         /* flags */
05514         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
05515         
05516         /* settings */
05517         ot->prop= RNA_def_enum(ot->srna, "type", axis_items, 0, "Axis", "Axis tag names with.");
05518 }
05519 
05520 
05521 
05522 /* if editbone (partial) selected, copy data */
05523 /* context; editmode armature, with mirror editing enabled */
05524 void transform_armature_mirror_update(Object *obedit)
05525 {
05526         bArmature *arm= obedit->data;
05527         EditBone *ebo, *eboflip;
05528         
05529         for (ebo= arm->edbo->first; ebo; ebo=ebo->next) {
05530                 /* no layer check, correct mirror is more important */
05531                 if (ebo->flag & (BONE_TIPSEL|BONE_ROOTSEL)) {
05532                         eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebo);
05533                         
05534                         if (eboflip) {
05535                                 /* we assume X-axis flipping for now */
05536                                 if (ebo->flag & BONE_TIPSEL) {
05537                                         EditBone *children;
05538                                         
05539                                         eboflip->tail[0]= -ebo->tail[0];
05540                                         eboflip->tail[1]= ebo->tail[1];
05541                                         eboflip->tail[2]= ebo->tail[2];
05542                                         eboflip->rad_tail= ebo->rad_tail;
05543                                         eboflip->roll= -ebo->roll;
05544 
05545                                         /* Also move connected children, in case children's name aren't mirrored properly */
05546                                         for (children=arm->edbo->first; children; children=children->next) {
05547                                                 if (children->parent == eboflip && children->flag & BONE_CONNECTED) {
05548                                                         copy_v3_v3(children->head, eboflip->tail);
05549                                                         children->rad_head = ebo->rad_tail;
05550                                                 }
05551                                         }
05552                                 }
05553                                 if (ebo->flag & BONE_ROOTSEL) {
05554                                         eboflip->head[0]= -ebo->head[0];
05555                                         eboflip->head[1]= ebo->head[1];
05556                                         eboflip->head[2]= ebo->head[2];
05557                                         eboflip->rad_head= ebo->rad_head;
05558                                         eboflip->roll= -ebo->roll;
05559                                         
05560                                         /* Also move connected parent, in case parent's name isn't mirrored properly */
05561                                         if (eboflip->parent && eboflip->flag & BONE_CONNECTED)
05562                                         {
05563                                                 EditBone *parent = eboflip->parent;
05564                                                 copy_v3_v3(parent->tail, eboflip->head);
05565                                                 parent->rad_tail = ebo->rad_head;
05566                                         }
05567                                 }
05568                                 if (ebo->flag & BONE_SELECTED) {
05569                                         eboflip->dist= ebo->dist;
05570                                         eboflip->roll= -ebo->roll;
05571                                         eboflip->xwidth= ebo->xwidth;
05572                                         eboflip->zwidth= ebo->zwidth;
05573                                 }
05574                         }
05575                 }
05576         }
05577 }
05578 
05579 
05580 /*****************************************************************************************************/
05581 /*************************************** SKELETON GENERATOR ******************************************/
05582 /*****************************************************************************************************/
05583 
05584 #if 0
05585 
05586 /**************************************** SUBDIVISION ALGOS ******************************************/
05587 
05588 EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
05589 {
05590         bArmature *arm= obedit->data;
05591         EditBone *lastBone = NULL;
05592         
05593         if (scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
05594         {
05595                 ReebArcIterator arc_iter;
05596                 BArcIterator *iter = (BArcIterator*)&arc_iter;
05597                 float *previous = NULL, *current = NULL;
05598                 EditBone *child = NULL;
05599                 EditBone *parent = NULL;
05600                 EditBone *root = NULL;
05601                 float angleLimit = (float)cos(scene->toolsettings->skgen_angle_limit * M_PI / 180.0f);
05602                 
05603                 parent = ED_armature_edit_bone_add(arm, "Bone");
05604                 parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
05605                 copy_v3_v3(parent->head, head->p);
05606                 
05607                 root = parent;
05608                 
05609                 initArcIterator(iter, arc, head);
05610                 IT_next(iter);
05611                 previous = iter->p;
05612                 
05613                 for (IT_next(iter);
05614                         IT_stopped(iter) == 0;
05615                         previous = iter->p, IT_next(iter))
05616                 {
05617                         float vec1[3], vec2[3];
05618                         float len1, len2;
05619                         
05620                         current = iter->p;
05621 
05622                         sub_v3_v3v3(vec1, previous, parent->head);
05623                         sub_v3_v3v3(vec2, current, previous);
05624 
05625                         len1 = normalize_v3(vec1);
05626                         len2 = normalize_v3(vec2);
05627 
05628                         if (len1 > 0.0f && len2 > 0.0f && dot_v3v3(vec1, vec2) < angleLimit)
05629                         {
05630                                 copy_v3_v3(parent->tail, previous);
05631 
05632                                 child = ED_armature_edit_bone_add(arm, "Bone");
05633                                 copy_v3_v3(child->head, parent->tail);
05634                                 child->parent = parent;
05635                                 child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
05636                                 
05637                                 parent = child; /* new child is next parent */
05638                         }
05639                 }
05640                 copy_v3_v3(parent->tail, tail->p);
05641                 
05642                 /* If the bone wasn't subdivided, delete it and return NULL
05643                  * to let subsequent subdivision methods do their thing. 
05644                  * */
05645                 if (parent == root)
05646                 {
05647                         if(parent==arm->act_edbone) arm->act_edbone= NULL;
05648                         ED_armature_edit_bone_remove(arm, parent);
05649                         parent = NULL;
05650                 }
05651                 
05652                 lastBone = parent; /* set last bone in the chain */
05653         }
05654         
05655         return lastBone;
05656 }
05657 
05658 EditBone * test_subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
05659 {
05660         EditBone *lastBone = NULL;
05661 
05662         if (scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
05663         {
05664                 float invmat[4][4]= MAT4_UNITY;
05665                 float tmat[3][3]= MAT3_UNITY;
05666                 ReebArcIterator arc_iter;
05667                 BArcIterator *iter = (BArcIterator*)&arc_iter;
05668                 bArmature *arm= obedit->data;
05669                 
05670                 initArcIterator(iter, arc, head);
05671                 
05672                 lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
05673         }
05674         
05675         return lastBone;
05676 }
05677 
05678 float arcLengthRatio(ReebArc *arc)
05679 {
05680         float arcLength = 0.0f;
05681         float embedLength = 0.0f;
05682         int i;
05683         
05684         arcLength = len_v3v3(arc->head->p, arc->tail->p);
05685         
05686         if (arc->bcount > 0)
05687         {
05688                 /* Add the embedding */
05689                 for ( i = 1; i < arc->bcount; i++)
05690                 {
05691                         embedLength += len_v3v3(arc->buckets[i - 1].p, arc->buckets[i].p);
05692                 }
05693                 /* Add head and tail -> embedding vectors */
05694                 embedLength += len_v3v3(arc->head->p, arc->buckets[0].p);
05695                 embedLength += len_v3v3(arc->tail->p, arc->buckets[arc->bcount - 1].p);
05696         }
05697         else
05698         {
05699                 embedLength = arcLength;
05700         }
05701         
05702         return embedLength / arcLength; 
05703 }
05704 
05705 EditBone * test_subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
05706 {
05707         EditBone *lastBone = NULL;
05708         if ((scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
05709                 arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
05710         {
05711                 float invmat[4][4]= MAT4_UNITY;
05712                 float tmat[3][3]= MAT3_UNITY;
05713                 ReebArcIterator arc_iter;
05714                 BArcIterator *iter = (BArcIterator*)&arc_iter;
05715                 bArmature *arm= obedit->data;
05716                 
05717                 initArcIterator(iter, arc, head);
05718                 
05719                 lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
05720         }
05721         
05722         return lastBone;
05723 }
05724 
05725 /***************************************** MAIN ALGORITHM ********************************************/
05726 
05727 void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg)
05728 {
05729         Object *obedit= scene->obedit; // XXX get from context
05730         GHash *arcBoneMap = NULL;
05731         ReebArc *arc = NULL;
05732         ReebNode *node = NULL;
05733         Object *src = NULL;
05734         Object *dst = NULL;
05735         
05736         src = scene->basact->object;
05737         
05738         if (obedit != NULL)
05739         {
05740                 ED_armature_from_edit(obedit);
05741                 ED_armature_edit_free(obedit);
05742         }
05743         
05744         dst = add_object(scene, OB_ARMATURE);
05745         ED_object_base_init_transform(NULL, scene->basact, NULL, NULL);         // XXX NULL is C, loc, rot
05746         obedit= scene->basact->object;
05747         
05748         /* Copy orientation from source */
05749         copy_v3_v3(dst->loc, src->obmat[3]);
05750         mat4_to_eul( dst->rot,src->obmat);
05751         mat4_to_size( dst->size,src->obmat);
05752         
05753         where_is_object(scene, obedit);
05754         
05755         ED_armature_to_edit(obedit);
05756 
05757         arcBoneMap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "SkeletonFromReebGraph gh");
05758         
05759         BLI_markdownSymmetry((BGraph*)rg, rg->nodes.first, scene->toolsettings->skgen_symmetry_limit);
05760         
05761         for (arc = rg->arcs.first; arc; arc = arc->next) 
05762         {
05763                 EditBone *lastBone = NULL;
05764                 ReebNode *head, *tail;
05765                 int i;
05766 
05767                 /* Find out the direction of the arc through simple heuristics (in order of priority) :
05768                  * 
05769                  * 1- Arcs on primary symmetry axis (symmetry == 1) point up (head: high weight -> tail: low weight)
05770                  * 2- Arcs starting on a primary axis point away from it (head: node on primary axis)
05771                  * 3- Arcs point down (head: low weight -> tail: high weight)
05772                  *
05773                  * Finally, the arc direction is stored in its flag: 1 (low -> high), -1 (high -> low)
05774                  */
05775 
05776                 /* if arc is a symmetry axis, internal bones go up the tree */          
05777                 if (arc->symmetry_level == 1 && arc->tail->degree != 1)
05778                 {
05779                         head = arc->tail;
05780                         tail = arc->head;
05781                         
05782                         arc->flag = -1; /* mark arc direction */
05783                 }
05784                 /* Bones point AWAY from the symmetry axis */
05785                 else if (arc->head->symmetry_level == 1)
05786                 {
05787                         head = arc->head;
05788                         tail = arc->tail;
05789                         
05790                         arc->flag = 1; /* mark arc direction */
05791                 }
05792                 else if (arc->tail->symmetry_level == 1)
05793                 {
05794                         head = arc->tail;
05795                         tail = arc->head;
05796                         
05797                         arc->flag = -1; /* mark arc direction */
05798                 }
05799                 /* otherwise, always go from low weight to high weight */
05800                 else
05801                 {
05802                         head = arc->head;
05803                         tail = arc->tail;
05804                         
05805                         arc->flag = 1; /* mark arc direction */
05806                 }
05807                 
05808                 /* Loop over subdivision methods */     
05809                 for (i = 0; lastBone == NULL && i < SKGEN_SUB_TOTAL; i++)
05810                 {
05811                         switch(scene->toolsettings->skgen_subdivisions[i])
05812                         {
05813                                 case SKGEN_SUB_LENGTH:
05814                                         lastBone = test_subdivideByLength(scene, obedit, arc, head, tail);
05815                                         break;
05816                                 case SKGEN_SUB_ANGLE:
05817                                         lastBone = subdivideByAngle(scene, obedit, arc, head, tail);
05818                                         break;
05819                                 case SKGEN_SUB_CORRELATION:
05820                                         lastBone = test_subdivideByCorrelation(scene, obedit, arc, head, tail);
05821                                         break;
05822                         }
05823                 }
05824         
05825                 if (lastBone == NULL)
05826                 {
05827                         EditBone        *bone;
05828                         bone = ED_armature_edit_bone_add(obedit->data, "Bone");
05829                         bone->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
05830                         
05831                         copy_v3_v3(bone->head, head->p);
05832                         copy_v3_v3(bone->tail, tail->p);
05833                         
05834                         /* set first and last bone, since there's only one */
05835                         lastBone = bone;
05836                 }
05837                 
05838                 BLI_ghash_insert(arcBoneMap, arc, lastBone);
05839         }
05840 
05841         /* Second pass, setup parent relationship between arcs */
05842         for (node = rg->nodes.first; node; node = node->next)
05843         {
05844                 ReebArc *incomingArc = NULL;
05845                 int i;
05846 
05847                 for (i = 0; i < node->degree; i++)
05848                 {
05849                         arc = (ReebArc*)node->arcs[i];
05850 
05851                         /* if arc is incoming into the node */
05852                         if ((arc->head == node && arc->flag == -1) || (arc->tail == node && arc->flag == 1))
05853                         {
05854                                 if (incomingArc == NULL)
05855                                 {
05856                                         incomingArc = arc;
05857                                         /* loop further to make sure there's only one incoming arc */
05858                                 }
05859                                 else
05860                                 {
05861                                         /* skip this node if more than one incomingArc */
05862                                         incomingArc = NULL;
05863                                         break; /* No need to look further, we are skipping already */
05864                                 }
05865                         }
05866                 }
05867 
05868                 if (incomingArc != NULL)
05869                 {
05870                         EditBone *parentBone = BLI_ghash_lookup(arcBoneMap, incomingArc);
05871 
05872                         /* Look for outgoing arcs and parent their bones */
05873                         for (i = 0; i < node->degree; i++)
05874                         {
05875                                 arc = node->arcs[i];
05876 
05877                                 /* if arc is outgoing from the node */
05878                                 if ((arc->head == node && arc->flag == 1) || (arc->tail == node && arc->flag == -1))
05879                                 {
05880                                         EditBone *childBone = BLI_ghash_lookup(arcBoneMap, arc);
05881 
05882                                         /* find the root bone */
05883                                         while(childBone->parent != NULL)
05884                                         {
05885                                                 childBone = childBone->parent;
05886                                         }
05887 
05888                                         childBone->parent = parentBone;
05889                                         childBone->flag |= BONE_CONNECTED;
05890                                 }
05891                         }
05892                 }
05893         }
05894         
05895         BLI_ghash_free(arcBoneMap, NULL, NULL);
05896 }
05897 
05898 void generateSkeleton(Scene *scene)
05899 {
05900         ReebGraph *reebg;
05901         
05902 //      setcursor_space(SPACE_VIEW3D, CURSOR_WAIT);
05903         
05904         reebg = BIF_ReebGraphFromEditMesh();
05905 
05906         generateSkeletonFromReebGraph(scene, reebg);
05907 
05908         REEB_freeGraph(reebg);
05909 
05910         //setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
05911 }
05912 
05913 #endif