RNA
[blender.git] / source / blender / editors / armature / editarmature.c
index 7a17a9dc9a65efc90163b8494be479b1419f9023..7155bdd6850b3940f912c3dfb349da6165ddaf92 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "MEM_guardedalloc.h"
 
-#include "BMF_Api.h"
-
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_constraint_types.h"
@@ -75,6 +73,7 @@
 
 #include "BIF_gl.h"
 #include "BIF_transform.h"
+#include "BIF_generate.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -463,13 +462,16 @@ static EditBone *editbone_name_exists (ListBase *edbo, char *name)
 }
 
 /* note: there's a unique_bone_name() too! */
-void unique_editbone_name (ListBase *edbo, char *name)
+void unique_editbone_name (ListBase *edbo, char *name, EditBone *bone)
 {
+       EditBone *dupli;
        char            tempname[64];
        int                     number;
        char            *dot;
+
+       dupli = editbone_name_exists(edbo, name);
        
-       if (editbone_name_exists(edbo, name)) {
+       if (dupli && bone != dupli) {
                /*      Strip off the suffix, if it's a number */
                number= strlen(name);
                if (number && isdigit(name[number-1])) {
@@ -679,7 +681,7 @@ int join_armature(Scene *scene, View3D *v3d)
        
        /*      Ensure we're not in editmode and that the active object is an armature*/
        if (ob->type!=OB_ARMATURE) return 0;
-       if(arm->edbo) return 0;
+       if (arm->edbo) return 0;
        
        if (object_data_is_libdata(ob)) {
                error_libdata();
@@ -717,7 +719,7 @@ int join_armature(Scene *scene, View3D *v3d)
                                        curbone= editbone_name_exists(curarm->edbo, pchan->name);
                                        
                                        /* Get new name */
-                                       unique_editbone_name(arm->edbo, curbone->name);
+                                       unique_editbone_name(arm->edbo, curbone->name, NULL);
                                        
                                        /* Transform the bone */
                                        {
@@ -732,6 +734,7 @@ int join_armature(Scene *scene, View3D *v3d)
                                                VecSubf(delta, curbone->tail, curbone->head);
                                                vec_roll_to_mat3(delta, curbone->roll, temp);
                                                
+                                               Mat4One(premat); /* Mat4MulMat34 only sets 3x3 part */
                                                Mat4MulMat34(premat, temp, mat);
                                                
                                                Mat4MulVecfl(mat, curbone->head);
@@ -1173,7 +1176,6 @@ static void bone_setflag (int *bone, int flag, short mode)
                                *bone &= ~flag;
                        else
                                *bone ^= flag;
-
                }
                else {
                        if (mode == 2)
@@ -1348,11 +1350,11 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *ev
        return OPERATOR_FINISHED;
 }
 
-void POSE_OT_select_connected(wmOperatorType *ot)
+void POSE_OT_select_linked(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Connected";
-       ot->idname= "POSE_OT_select_connected";
+       ot->idname= "POSE_OT_select_linked";
        
        /* api callbacks */
        ot->exec= NULL;
@@ -1370,7 +1372,7 @@ void POSE_OT_select_connected(wmOperatorType *ot)
 
 /* called in space.c */
 /* previously "selectconnected_armature" */
-static int armature_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        bArmature *arm;
        EditBone *bone, *curBone, *next;
@@ -1442,15 +1444,15 @@ static int armature_select_connected_invoke(bContext *C, wmOperator *op, wmEvent
        return OPERATOR_FINISHED;
 }
 
-void ARMATURE_OT_select_connected(wmOperatorType *ot)
+void ARMATURE_OT_select_linked(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Select Connected";
-       ot->idname= "ARMATURE_OT_select_connected";
+       ot->idname= "ARMATURE_OT_select_linked";
        
        /* api callbacks */
        ot->exec= NULL;
-       ot->invoke= armature_select_connected_invoke;
+       ot->invoke= armature_select_linked_invoke;
        ot->poll= ED_operator_editarmature;
        
        /* flags */
@@ -1673,11 +1675,11 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void ARMATURE_OT_delete_selected(wmOperatorType *ot)
+void ARMATURE_OT_delete(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Delete Selected Bone(s)";
-       ot->idname= "ARMATURE_OT_delete_selected";
+       ot->idname= "ARMATURE_OT_delete";
        
        /* api callbacks */
        ot->invoke = WM_operator_confirm;
@@ -1759,6 +1761,8 @@ void mouse_armature(bContext *C, short mval[2], int extend)
 
        view3d_set_viewcontext(C, &vc);
        
+       BIF_sk_selectStroke(C, mval, extend);
+       
        nearBone= get_nearest_editbonepoint(&vc, mval, arm->edbo, 1, &selmask);
        if (nearBone) {
 
@@ -1852,6 +1856,8 @@ void ED_armature_to_edit(Object *ob)
        ED_armature_edit_free(ob);
        arm->edbo= MEM_callocN(sizeof(ListBase), "edbo armature");
        make_boneList(arm->edbo, &arm->bonebase,NULL);
+
+//     BIF_freeTemplates(); /* force template update when entering editmode */
 }
 
 
@@ -1951,9 +1957,9 @@ void auto_align_ebone_tocursor(Scene *scene, View3D *v3d, EditBone *ebone)
 
 
 static EnumPropertyItem prop_calc_roll_types[] = {
-       {0, "GLOBALUP", "Z-Axis Up", ""},
-       {1, "CURSOR", "Z-Axis to Cursor", ""},
-       {0, NULL, NULL, NULL}
+       {0, "GLOBALUP", 0, "Z-Axis Up", ""},
+       {1, "CURSOR", 0, "Z-Axis to Cursor", ""},
+       {0, NULL, 0, NULL, NULL}
 };
 
 static int armature_calc_roll_exec(bContext *C, wmOperator *op) 
@@ -2086,14 +2092,12 @@ void undo_push_armature(bContext *C, char *name)
 /* *************** Adding stuff in editmode *************** */
 
 /* default bone add, returns it selected, but without tail set */
-static EditBone *add_editbone(Object *obedit, char *name)
+EditBone *addEditBone(bArmature *arm, char *name)
 {
-       bArmature *arm= obedit->data;
-       
        EditBone *bone= MEM_callocN(sizeof(EditBone), "eBone");
        
        BLI_strncpy(bone->name, name, 32);
-       unique_editbone_name(arm->edbo, bone->name);
+       unique_editbone_name(arm->edbo, bone->name, NULL);
        
        BLI_addtail(arm->edbo, bone);
        
@@ -2112,7 +2116,16 @@ static EditBone *add_editbone(Object *obedit, char *name)
        return bone;
 }
 
-static void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, short newob)
+/* default bone add, returns it selected, but without tail set */
+static EditBone *add_editbone(Object *obedit, char *name)
+{
+       bArmature *arm= obedit->data;
+
+       return addEditBone(arm, name);
+}
+
+/* v3d and rv3d are allowed to be NULL */
+void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d)
 {
        Object *obedit= scene->obedit; // XXX get from context
        float           obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3];
@@ -2124,7 +2137,7 @@ static void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, sh
        Mat4Invert(obedit->imat, obedit->obmat);
        Mat4MulVecfl(obedit->imat, curs);
 
-       if ( !(newob) || (U.flag & USER_ADD_VIEWALIGNED) ) 
+       if (rv3d && (U.flag & USER_ADD_VIEWALIGNED))
                Mat3CpyMat4(obmat, rv3d->viewmat);
        else Mat3One(obmat);
        
@@ -2139,51 +2152,13 @@ static void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, sh
 
        VECCOPY(bone->head, curs);
        
-       if ( !(newob) || (U.flag & USER_ADD_VIEWALIGNED) )
+       if ( (U.flag & USER_ADD_VIEWALIGNED) )
                VecAddf(bone->tail, bone->head, imat[1]);       // bone with unit length 1
        else
                VecAddf(bone->tail, bone->head, imat[2]);       // bone with unit length 1, pointing up Z
        
 }
 
-void add_primitiveArmature(Scene *scene, View3D *v3d, int type)
-{
-       RegionView3D *rv3d= NULL; // XXX get from context
-       Object *obedit= scene->obedit; // XXX get from context
-       short newob=0;
-       
-       if(scene->id.lib) return;
-       
-       G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE);
-//     setcursor_space(SPACE_VIEW3D, CURSOR_STD);
-
-// XXX check_editmode(OB_ARMATURE);
-       
-       /* If we're not the "obedit", make a new object and enter editmode */
-       if (obedit==NULL) {
-               add_object(scene, OB_ARMATURE);
-               ED_object_base_init_from_view(NULL, BASACT);    // XXX NULL is C
-               obedit= BASACT->object;
-               
-               where_is_object(scene, obedit);
-               
-               ED_armature_to_edit(obedit);
-//             setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
-               newob=1;
-       }
-       
-       /* no primitive support yet */
-       add_primitive_bone(scene, v3d, rv3d, newob);
-       
-       //armature_sync_selection(arm->edbo); // XXX which armature?
-
-       if ((newob) && !(U.flag & USER_ADD_EDITMODE)) {
-               ED_armature_from_edit(scene, obedit);
-               ED_armature_edit_free(obedit);
-       }
-       
-       BIF_undo_push("Add primitive");
-}
 
 /* previously addvert_armature */
 /* the ctrl-click method */
@@ -2379,19 +2354,35 @@ static EditBone *get_named_editbone(ListBase *edbo, char *name)
        return NULL;
 }
 
-static void update_dup_subtarget(Object *obedit, EditBone *dupBone)
+/* Call this before doing any duplications
+ * */
+void preEditBoneDuplicate(ListBase *editbones)
+{
+       EditBone *eBone;
+       
+       /* clear temp */
+       for (eBone = editbones->first; eBone; eBone = eBone->next)
+       {
+               eBone->temp = NULL;
+       }
+}
+
+/*
+ * Note: When duplicating cross objects, editbones here is the list of bones
+ * from the SOURCE object but ob is the DESTINATION object
+ * */
+void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Object *src_ob, Object *dst_ob)
 {
        /* If an edit bone has been duplicated, lets
         * update it's constraints if the subtarget
         * they point to has also been duplicated
         */
-       bArmature    *arm = obedit->data;
        EditBone     *oldtarget, *newtarget;
        bPoseChannel *chan;
        bConstraint  *curcon;
        ListBase     *conlist;
        
-       if ( (chan = verify_pose_channel(obedit->pose, dupBone->name)) ) {
+       if ( (chan = verify_pose_channel(dst_ob->pose, dupBone->name)) ) {
                if ( (conlist = &chan->constraints) ) {
                        for (curcon = conlist->first; curcon; curcon=curcon->next) {
                                /* does this constraint have a subtarget in
@@ -2405,14 +2396,15 @@ static void update_dup_subtarget(Object *obedit, EditBone *dupBone)
                                        cti->get_constraint_targets(curcon, &targets);
                                        
                                        for (ct= targets.first; ct; ct= ct->next) {
-                                               if ((ct->tar == obedit) && (ct->subtarget[0])) {
-                                                       oldtarget = get_named_editbone(arm->edbo, ct->subtarget);
+                                               if ((ct->tar == src_ob) && (ct->subtarget[0])) {
+                                                       ct->tar = dst_ob; /* update target */ 
+                                                       oldtarget = get_named_editbone(editbones, ct->subtarget);
                                                        if (oldtarget) {
                                                                /* was the subtarget bone duplicated too? If
                                                                 * so, update the constraint to point at the 
                                                                 * duplicate of the old subtarget.
                                                                 */
-                                                               if (oldtarget->flag & BONE_SELECTED){
+                                                               if (oldtarget->temp) {
                                                                        newtarget = (EditBone *) oldtarget->temp;
                                                                        strcpy(ct->subtarget, newtarget->name);
                                                                }
@@ -2428,6 +2420,79 @@ static void update_dup_subtarget(Object *obedit, EditBone *dupBone)
        }
 }
 
+void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob)
+{
+       updateDuplicateSubtargetObjects(dupBone, editbones, ob, ob);
+}
+
+
+EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob)
+{
+       EditBone *eBone = MEM_callocN(sizeof(EditBone), "addup_editbone");
+       
+       /*      Copy data from old bone to new bone */
+       memcpy(eBone, curBone, sizeof(EditBone));
+       
+       curBone->temp = eBone;
+       eBone->temp = curBone;
+       
+       if (name != NULL)
+       {
+               BLI_strncpy(eBone->name, name, 32);
+       }
+
+       unique_editbone_name(editbones, eBone->name, NULL);
+       BLI_addtail(editbones, eBone);
+       
+       /* Lets duplicate the list of constraints that the
+        * current bone has.
+        */
+       if (src_ob->pose) {
+               bPoseChannel *chanold, *channew;
+               ListBase     *listold, *listnew;
+               
+               chanold = verify_pose_channel(src_ob->pose, curBone->name);
+               if (chanold) {
+                       listold = &chanold->constraints;
+                       if (listold) {
+                               /* WARNING: this creates a new posechannel, but there will not be an attached bone 
+                                *              yet as the new bones created here are still 'EditBones' not 'Bones'. 
+                                */
+                               channew = 
+                                       verify_pose_channel(dst_ob->pose, eBone->name);
+                               if (channew) {
+                                       /* copy transform locks */
+                                       channew->protectflag = chanold->protectflag;
+                                       
+                                       /* copy bone group */
+                                       channew->agrp_index= chanold->agrp_index;
+                                       
+                                       /* ik (dof) settings */
+                                       channew->ikflag = chanold->ikflag;
+                                       VECCOPY(channew->limitmin, chanold->limitmin);
+                                       VECCOPY(channew->limitmax, chanold->limitmax);
+                                       VECCOPY(channew->stiffness, chanold->stiffness);
+                                       channew->ikstretch= chanold->ikstretch;
+                                       
+                                       /* constraints */
+                                       listnew = &channew->constraints;
+                                       copy_constraints(listnew, listold);
+                                       
+                                       /* custom shape */
+                                       channew->custom= chanold->custom;
+                               }
+                       }
+               }
+       }
+       
+       return eBone;
+}
+
+EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob)
+{
+       return duplicateEditBoneObjects(curBone, name, editbones, ob, ob);
+}
+
 /* previously adduplicate_armature */
 static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
 {
@@ -2445,6 +2510,8 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
        
        armature_sync_selection(arm->edbo); // XXX why is this needed?
 
+       preEditBoneDuplicate(arm->edbo);
+
        /* Select mirrored bones */
        if (arm->flag & ARM_MIRROR_EDIT) {
                for (curBone=arm->edbo->first; curBone; curBone=curBone->next) {
@@ -2457,6 +2524,7 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
                        }
                }
        }
+
        
        /*      Find the selected bones and duplicate them as needed */
        for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
@@ -2465,13 +2533,13 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
                                eBone=MEM_callocN(sizeof(EditBone), "addup_editbone");
                                eBone->flag |= BONE_SELECTED;
                                
-                               /*      Copy data from old bone to new bone */
+                               /* Copy data from old bone to new bone */
                                memcpy(eBone, curBone, sizeof(EditBone));
                                
                                curBone->temp = eBone;
                                eBone->temp = curBone;
                                
-                               unique_editbone_name(arm->edbo, eBone->name);
+                               unique_editbone_name(arm->edbo, eBone->name, NULL);
                                BLI_addtail(arm->edbo, eBone);
                                if (!firstDup)
                                        firstDup=eBone;
@@ -2526,33 +2594,35 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
                        if (curBone->flag & BONE_SELECTED) {
                                eBone=(EditBone*) curBone->temp;
                                
-                               /*      If this bone has no parent,
-                               Set the duplicate->parent to NULL
-                               */
-                               if (!curBone->parent)
+                               if (!curBone->parent) {
+                                       /* If this bone has no parent,
+                                        * Set the duplicate->parent to NULL
+                                        */
                                        eBone->parent = NULL;
-                               /*      If this bone has a parent that IS selected,
-                                       Set the duplicate->parent to the curBone->parent->duplicate
-                                       */
-                               else if (curBone->parent->flag & BONE_SELECTED)
+                               }
+                               else if (curBone->parent->temp) {
+                                       /* If this bone has a parent that was duplicated,
+                                        * Set the duplicate->parent to the curBone->parent->temp
+                                        */
                                        eBone->parent= (EditBone *)curBone->parent->temp;
-                               /*      If this bone has a parent that IS not selected,
-                                       Set the duplicate->parent to the curBone->parent
-                                       */
+                               }
                                else {
+                                       /* If this bone has a parent that IS not selected,
+                                        * Set the duplicate->parent to the curBone->parent
+                                        */
                                        eBone->parent=(EditBone*) curBone->parent; 
                                        eBone->flag &= ~BONE_CONNECTED;
                                }
                                
                                /* Lets try to fix any constraint subtargets that might
-                                       have been duplicated */
-                               update_dup_subtarget(obedit, eBone);
+                                * have been duplicated 
+                                */
+                               updateDuplicateSubtarget(eBone, arm->edbo, obedit);
                        }
                }
        } 
        
        /*      Deselect the old bones and select the new ones */
-       
        for (curBone=arm->edbo->first; curBone && curBone!=firstDup; curBone=curBone->next) {
                if (EBONE_VISIBLE(arm, curBone))
                        curBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL | BONE_ACTIVE);
@@ -2560,9 +2630,6 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *op)
 
        WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, obedit);
        
-// XXX BIF_TransformSetUndo("Add Duplicate");
-//     initTransform(TFM_TRANSLATION, CTX_NO_PET);
-//     Transform();
        return OPERATOR_FINISHED;
 }
 
@@ -3161,7 +3228,7 @@ static int armature_extrude_exec(bContext *C, wmOperator *op)
                                                        else strcat(newbone->name, "_R");
                                                }
                                        }
-                                       unique_editbone_name(arm->edbo, newbone->name);
+                                       unique_editbone_name(arm->edbo, newbone->name, NULL);
                                        
                                        /* Add the new bone to the list */
                                        BLI_addtail(arm->edbo, newbone);
@@ -3338,7 +3405,7 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op)
                        
                        newbone->flag |= BONE_CONNECTED;
                        
-                       unique_editbone_name(arm->edbo, newbone->name);
+                       unique_editbone_name(arm->edbo, newbone->name, NULL);
                        
                        /* correct parent bones */
                        for (tbone = arm->edbo->first; tbone; tbone=tbone->next) {
@@ -3392,11 +3459,13 @@ void ARMATURE_OT_subdivide_multi(wmOperatorType *ot)
 
 static int armature_subdivs_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       uiMenuItem *head;
+       uiPopupMenu *pup;
+       uiLayout *layout;
 
-       head= uiPupMenuBegin("Subdivision Type", 0);
-       uiMenuItemsEnumO(head, "ARMATURE_OT_subdivs", "type");
-       uiPupMenuEnd(C, head);
+       pup= uiPupMenuBegin(C, "Subdivision Type", 0);
+       layout= uiPupMenuLayout(pup);
+       uiItemsEnumO(layout, "ARMATURE_OT_subdivs", "type");
+       uiPupMenuEnd(C, pup);
        
        return OPERATOR_CANCELLED;
 }
@@ -3420,9 +3489,9 @@ static int armature_subdivs_exec(bContext *C, wmOperator *op)
 void ARMATURE_OT_subdivs(wmOperatorType *ot)
 {
        static EnumPropertyItem type_items[]= {
-               {0, "SIMPLE", "Simple", ""},
-               {1, "MULTI", "Multi", ""},
-               {0, NULL, NULL}};
+               {0, "SIMPLE", 0, "Simple", ""},
+               {1, "MULTI", 0, "Multi", ""},
+               {0, NULL, 0, NULL, NULL}};
 
        /* identifiers */
        ot->name= "subdivs";
@@ -3538,6 +3607,8 @@ void ARMATURE_OT_switch_direction(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 /* ***************** Parenting *********************** */
+
+/* armature parenting options */
 #define ARM_PAR_CONNECT 1
 #define ARM_PAR_OFFSET 2
 
@@ -3598,9 +3669,9 @@ static void bone_connect_to_new_parent(ListBase *edbo, EditBone *selbone, EditBo
 }
 
 static EnumPropertyItem prop_editarm_make_parent_types[] = {
-       {ARM_PAR_CONNECT, "CONNECTED", "Connected", ""},
-       {ARM_PAR_OFFSET, "OFFSET", "Keep Offset", ""},
-       {0, NULL, NULL, NULL}
+       {ARM_PAR_CONNECT, "CONNECTED", 0, "Connected", ""},
+       {ARM_PAR_OFFSET, "OFFSET", 0, "Keep Offset", ""},
+       {0, NULL, 0, NULL, NULL}
 };
 
 static int armature_parent_set_exec(bContext *C, wmOperator *op) 
@@ -3647,14 +3718,19 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
                /* Parent 'selected' bones to the active one
                 * - the context iterator contains both selected bones and their mirrored copies,
                 *   so we assume that unselected bones are mirrored copies of some selected bone
+                * - since the active one (and/or its mirror) will also be selected, we also need 
+                *      to check that we are not trying to opearate on them, since such an operation 
+                *      would cause errors
                 */
                
-               /* align selected bones to the active one */
+               /* parent selected bones to the active one */
                CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
-                       if (ebone->flag & BONE_SELECTED) 
-                               bone_connect_to_new_parent(arm->edbo, ebone, actbone, val);
-                       else
-                               bone_connect_to_new_parent(arm->edbo, ebone, actmirb, val);
+                       if (ELEM(ebone, actbone, actmirb) == 0) {
+                               if (ebone->flag & BONE_SELECTED) 
+                                       bone_connect_to_new_parent(arm->edbo, ebone, actbone, val);
+                               else
+                                       bone_connect_to_new_parent(arm->edbo, ebone, actmirb, val);
+                       }
                }
                CTX_DATA_END;
        }
@@ -3669,7 +3745,8 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
 static int armature_parent_set_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
        EditBone *actbone = CTX_data_active_bone(C);
-       uiMenuItem *head= uiPupMenuBegin("Make Parent ", 0);
+       uiPopupMenu *pup= uiPupMenuBegin(C, "Make Parent ", 0);
+       uiLayout *layout= uiPupMenuLayout(pup);
        int allchildbones = 0;
        
        CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
@@ -3679,13 +3756,13 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *op, wmEvent *even
        }
        CTX_DATA_END;
 
-       uiMenuItemEnumO(head, "", 0, "ARMATURE_OT_set_parent", "type", ARM_PAR_CONNECT);
+       uiItemEnumO(layout, NULL, 0, "ARMATURE_OT_parent_set", "type", ARM_PAR_CONNECT);
        
        /* ob becomes parent, make the associated menus */
        if (allchildbones)
-               uiMenuItemEnumO(head, "", 0, "ARMATURE_OT_set_parent", "type", ARM_PAR_OFFSET); 
+               uiItemEnumO(layout, NULL, 0, "ARMATURE_OT_parent_set", "type", ARM_PAR_OFFSET); 
                
-       uiPupMenuEnd(C, head);
+       uiPupMenuEnd(C, pup);
        
        return OPERATOR_CANCELLED;
 }
@@ -3694,7 +3771,7 @@ void ARMATURE_OT_parent_set(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Make Parent";
-       ot->idname= "ARMATURE_OT_set_parent";
+       ot->idname= "ARMATURE_OT_parent_set";
        
        /* api callbacks */
        ot->invoke = armature_parent_set_invoke;
@@ -3708,9 +3785,9 @@ void ARMATURE_OT_parent_set(wmOperatorType *ot)
 }
 
 static EnumPropertyItem prop_editarm_clear_parent_types[] = {
-       {1, "CLEAR", "Clear Parent", ""},
-       {2, "DISCONNECT", "Disconnect Bone", ""},
-       {0, NULL, NULL, NULL}
+       {1, "CLEAR", 0, "Clear Parent", ""},
+       {2, "DISCONNECT", 0, "Disconnect Bone", ""},
+       {0, NULL, 0, NULL, NULL}
 };
 
 static void editbone_clear_parent(EditBone *ebone, int mode)
@@ -3747,7 +3824,7 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Clear Parent";
-       ot->idname= "ARMATURE_OT_clear_parent";
+       ot->idname= "ARMATURE_OT_parent_clear";
        
        /* api callbacks */
        ot->invoke = WM_menu_invoke;
@@ -3762,7 +3839,7 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot)
 
 /* ****************  Selections  ******************/
 
-static int armature_selection_invert_exec(bContext *C, wmOperator *op)
+static int armature_select_invert_exec(bContext *C, wmOperator *op)
 {
        /*      Set the flags */
        CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) {
@@ -3777,15 +3854,15 @@ static int armature_selection_invert_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void ARMATURE_OT_selection_invert(wmOperatorType *ot)
+void ARMATURE_OT_select_invert(wmOperatorType *ot)
 {
        
        /* identifiers */
        ot->name= "Invert Selection";
-       ot->idname= "ARMATURE_OT_selection_invert";
+       ot->idname= "ARMATURE_OT_select_invert";
        
        /* api callbacks */
-       ot->exec= armature_selection_invert_exec;
+       ot->exec= armature_select_invert_exec;
        ot->poll= ED_operator_editarmature;
        
        /* flags */
@@ -3820,12 +3897,12 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void ARMATURE_OT_de_select_all(wmOperatorType *ot)
+void ARMATURE_OT_select_all_toggle(wmOperatorType *ot)
 {
        
        /* identifiers */
        ot->name= "deselect all editbone";
-       ot->idname= "ARMATURE_OT_de_select_all";
+       ot->idname= "ARMATURE_OT_select_all_toggle";
        
        /* api callbacks */
        ot->exec= armature_de_select_all_exec;
@@ -3845,7 +3922,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
        bArmature *arm;
        EditBone *curbone, *pabone, *chbone;
        int direction = RNA_enum_get(op->ptr, "direction");
-       int add_to_sel = RNA_boolean_get(op->ptr, "add_to_sel");
+       int add_to_sel = RNA_boolean_get(op->ptr, "extend");
        
        ob= obedit;
        arm= (bArmature *)ob->data;
@@ -3896,9 +3973,9 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op)
 void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
 {
        static EnumPropertyItem direction_items[]= {
-       {BONE_SELECT_PARENT, "PARENT", "Select Parent", ""},
-       {BONE_SELECT_CHILD, "CHILD", "Select Child", ""},
-       {0, NULL, NULL, NULL}
+       {BONE_SELECT_PARENT, "PARENT", 0, "Select Parent", ""},
+       {BONE_SELECT_CHILD, "CHILD", 0, "Select Child", ""},
+       {0, NULL, 0, NULL, NULL}
        };
        
        /* identifiers */
@@ -3915,7 +3992,7 @@ void ARMATURE_OT_select_hierarchy(wmOperatorType *ot)
        /* props */
        RNA_def_enum(ot->srna, "direction", direction_items,
                     BONE_SELECT_PARENT, "Direction", "");
-       RNA_def_boolean(ot->srna, "add_to_sel", 0, "Add to Selection", "");
+       RNA_def_boolean(ot->srna, "extend", 0, "Add to Selection", "");
 }
 
 /* ***************** EditBone Alignment ********************* */
@@ -4013,14 +4090,19 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
                /* Align 'selected' bones to the active one
                 * - the context iterator contains both selected bones and their mirrored copies,
                 *   so we assume that unselected bones are mirrored copies of some selected bone
+                * - since the active one (and/or its mirror) will also be selected, we also need 
+                *      to check that we are not trying to opearate on them, since such an operation 
+                *      would cause errors
                 */
                
                /* align selected bones to the active one */
                CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
-                       if (ebone->flag & BONE_SELECTED)
-                               bone_align_to_bone(arm->edbo, ebone, actbone);
-                       else
-                               bone_align_to_bone(arm->edbo, ebone, actmirb);
+                       if (ELEM(ebone, actbone, actmirb) == 0) {
+                               if (ebone->flag & BONE_SELECTED)
+                                       bone_align_to_bone(arm->edbo, ebone, actbone);
+                               else
+                                       bone_align_to_bone(arm->edbo, ebone, actmirb);
+                       }
                }
                CTX_DATA_END;
        }
@@ -4032,11 +4114,11 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void ARMATURE_OT_align_bones(wmOperatorType *ot)
+void ARMATURE_OT_bones_align(wmOperatorType *ot)
 {
        /* identifiers */
        ot->name= "Align Bones";
-       ot->idname= "ARMATURE_OT_align_bones";
+       ot->idname= "ARMATURE_OT_bones_align";
        
        /* api callbacks */
        ot->invoke = WM_operator_confirm;
@@ -4741,7 +4823,7 @@ void POSE_OT_rot_clear(wmOperatorType *ot)
 
 /* ***************** selections ********************** */
 
-static int pose_selection_invert_exec(bContext *C, wmOperator *op)
+static int pose_select_invert_exec(bContext *C, wmOperator *op)
 {
        
        /*      Set the flags */
@@ -4756,15 +4838,15 @@ static int pose_selection_invert_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void POSE_OT_selection_invert(wmOperatorType *ot)
+void POSE_OT_select_invert(wmOperatorType *ot)
 {
        
        /* identifiers */
        ot->name= "Invert Selection";
-       ot->idname= "POSE_OT_selection_invert";
+       ot->idname= "POSE_OT_select_invert";
        
        /* api callbacks */
-       ot->exec= pose_selection_invert_exec;
+       ot->exec= pose_select_invert_exec;
        ot->poll= ED_operator_posemode;
        
        /* flags */
@@ -4792,12 +4874,12 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void POSE_OT_de_select_all(wmOperatorType *ot)
+void POSE_OT_select_all_toggle(wmOperatorType *ot)
 {
        
        /* identifiers */
        ot->name= "deselect all bones";
-       ot->idname= "POSE_OT_de_select_all";
+       ot->idname= "POSE_OT_select_all_toggle";
        
        /* api callbacks */
        ot->exec= pose_de_select_all_exec;
@@ -5036,7 +5118,7 @@ void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep)
                        
                        eBone= editbone_name_exists(arm->edbo, oldname);
                        if (eBone) {
-                               unique_editbone_name(arm->edbo, newname);
+                               unique_editbone_name(arm->edbo, newname, NULL);
                                BLI_strncpy(eBone->name, newname, MAXBONENAME);
                        }
                        else return;
@@ -5263,9 +5345,9 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
        
        if (scene->toolsettings->skgen_options & SKGEN_CUT_ANGLE)
        {
-               ReebArcIterator iter;
-               EmbedBucket *current = NULL;
-               EmbedBucket *previous = NULL;
+               ReebArcIterator arc_iter;
+               BArcIterator *iter = (BArcIterator*)&arc_iter;
+               float *previous = NULL, *current = NULL;
                EditBone *child = NULL;
                EditBone *parent = NULL;
                EditBone *root = NULL;
@@ -5277,22 +5359,28 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
                
                root = parent;
                
-               for (initArcIterator(&iter, arc, head), previous = nextBucket(&iter), current = nextBucket(&iter);
-                       current;
-                       previous = current, current = nextBucket(&iter))
+               initArcIterator(iter, arc, head);
+               IT_next(iter);
+               previous = iter->p;
+               
+               for (IT_next(iter);
+                       IT_stopped(iter) == 0;
+                       previous = iter->p, IT_next(iter))
                {
                        float vec1[3], vec2[3];
                        float len1, len2;
+                       
+                       current = iter->p;
 
-                       VecSubf(vec1, previous->p, parent->head);
-                       VecSubf(vec2, current->p, previous->p);
+                       VecSubf(vec1, previous, parent->head);
+                       VecSubf(vec2, current, previous);
 
                        len1 = Normalize(vec1);
                        len2 = Normalize(vec2);
 
                        if (len1 > 0.0f && len2 > 0.0f && Inpf(vec1, vec2) < angleLimit)
                        {
-                               VECCOPY(parent->tail, previous->p);
+                               VECCOPY(parent->tail, previous);
 
                                child = add_editbone(obedit, "Bone");
                                VECCOPY(child->head, parent->tail);
@@ -5319,182 +5407,29 @@ EditBone * subdivideByAngle(Scene *scene, Object *obedit, ReebArc *arc, ReebNode
        return lastBone;
 }
 
-float calcVariance(ReebArc *arc, int start, int end, float v0[3], float n[3])
+EditBone * test_subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
 {
-       int len = 2 + abs(end - start);
-       
-       if (len > 2)
-       {
-               ReebArcIterator iter;
-               EmbedBucket *bucket = NULL;
-               float avg_t = 0.0f;
-               float s_t = 0.0f;
-               float s_xyz = 0.0f;
-               
-               /* First pass, calculate average */
-               for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
-                       bucket;
-                       bucket = nextBucket(&iter))
-               {
-                       float v[3];
-                       
-                       VecSubf(v, bucket->p, v0);
-                       avg_t += Inpf(v, n);
-               }
-               
-               avg_t /= Inpf(n, n);
-               avg_t += 1.0f; /* adding start (0) and end (1) values */
-               avg_t /= len;
-               
-               /* Second pass, calculate s_xyz and s_t */
-               for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
-                       bucket;
-                       bucket = nextBucket(&iter))
-               {
-                       float v[3], d[3];
-                       float dt;
-                       
-                       VecSubf(v, bucket->p, v0);
-                       Projf(d, v, n);
-                       VecSubf(v, v, d);
-                       
-                       dt = VecLength(d) - avg_t;
-                       
-                       s_t += dt * dt;
-                       s_xyz += Inpf(v, v);
-               }
-               
-               /* adding start(0) and end(1) values to s_t */
-               s_t += (avg_t * avg_t) + (1 - avg_t) * (1 - avg_t);
-               
-               return s_xyz / s_t; 
-       }
-       else
-       {
-               return 0;
-       }
-}
-
-float calcDistance(ReebArc *arc, int start, int end, float head[3], float tail[3])
-{
-       ReebArcIterator iter;
-       EmbedBucket *bucket = NULL;
-       float max_dist = 0;
-       
-       /* calculate maximum distance */
-       for (initArcIterator2(&iter, arc, start, end), bucket = nextBucket(&iter);
-               bucket;
-               bucket = nextBucket(&iter))
-       {
-               float v1[3], v2[3], c[3];
-               float dist;
-               
-               VecSubf(v1, head, tail);
-               VecSubf(v2, bucket->p, tail);
-
-               Crossf(c, v1, v2);
-               
-               dist = Inpf(c, c) / Inpf(v1, v1);
-               
-               max_dist = dist > max_dist ? dist : max_dist;
-       }
-       
-       
-       return max_dist; 
-}
-
-EditBone * subdivideByCorrelation(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
-{
-       ReebArcIterator iter;
-       float n[3];
-       float ADAPTIVE_THRESHOLD = scene->toolsettings->skgen_correlation_limit;
        EditBone *lastBone = NULL;
-       
-       /* init iterator to get start and end from head */
-       initArcIterator(&iter, arc, head);
-       
-       /* Calculate overall */
-       VecSubf(n, arc->buckets[iter.end].p, head->p);
-       
+
        if (scene->toolsettings->skgen_options & SKGEN_CUT_CORRELATION)
        {
-               EmbedBucket *bucket = NULL;
-               EmbedBucket *previous = NULL;
-               EditBone *child = NULL;
-               EditBone *parent = NULL;
-               float normal[3] = {0, 0, 0};
-               float avg_normal[3];
-               int total = 0;
-               int boneStart = iter.start;
-               
-               parent = add_editbone(obedit, "Bone");
-               parent->flag = BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-               VECCOPY(parent->head, head->p);
+               float invmat[4][4] = {  {1, 0, 0, 0},
+                                                               {0, 1, 0, 0},
+                                                               {0, 0, 1, 0},
+                                                               {0, 0, 0, 1}};
+               float tmat[3][3] = {    {1, 0, 0},
+                                                               {0, 1, 0},
+                                                               {0, 0, 1}};
+               ReebArcIterator arc_iter;
+               BArcIterator *iter = (BArcIterator*)&arc_iter;
+               bArmature *arm= obedit->data;
                
-               for (previous = nextBucket(&iter), bucket = nextBucket(&iter);
-                       bucket;
-                       previous = bucket, bucket = nextBucket(&iter))
-               {
-                       float btail[3];
-                       float value = 0;
-
-                       if (scene->toolsettings->skgen_options & SKGEN_STICK_TO_EMBEDDING)
-                       {
-                               VECCOPY(btail, bucket->p);
-                       }
-                       else
-                       {
-                               float length;
-                               
-                               /* Calculate normal */
-                               VecSubf(n, bucket->p, parent->head);
-                               length = Normalize(n);
-                               
-                               total += 1;
-                               VecAddf(normal, normal, n);
-                               VECCOPY(avg_normal, normal);
-                               VecMulf(avg_normal, 1.0f / total);
-                                
-                               VECCOPY(btail, avg_normal);
-                               VecMulf(btail, length);
-                               VecAddf(btail, btail, parent->head);
-                       }
-
-                       if (scene->toolsettings->skgen_options & SKGEN_ADAPTIVE_DISTANCE)
-                       {
-                               value = calcDistance(arc, boneStart, iter.index, parent->head, btail);
-                       }
-                       else
-                       {
-                               float n[3];
-                               
-                               VecSubf(n, btail, parent->head);
-                               value = calcVariance(arc, boneStart, iter.index, parent->head, n);
-                       }
-
-                       if (value > ADAPTIVE_THRESHOLD)
-                       {
-                               VECCOPY(parent->tail, btail);
-
-                               child = add_editbone(obedit, "Bone");
-                               VECCOPY(child->head, parent->tail);
-                               child->parent = parent;
-                               child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-                               
-                               parent = child; // new child is next parent
-                               boneStart = iter.index; // start from end
-                               
-                               normal[0] = normal[1] = normal[2] = 0;
-                               total = 0;
-                       }
-               }
-
-               VECCOPY(parent->tail, tail->p);
+               initArcIterator(iter, arc, head);
                
-               lastBone = parent; /* set last bone in the chain */
+               lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextAdaptativeSubdivision);
        }
        
-       return lastBone;
+       return lastBone;
 }
 
 float arcLengthRatio(ReebArc *arc)
@@ -5524,108 +5459,26 @@ float arcLengthRatio(ReebArc *arc)
        return embedLength / arcLength; 
 }
 
-EditBone * subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
+EditBone * test_subdivideByLength(Scene *scene, Object *obedit, ReebArc *arc, ReebNode *head, ReebNode *tail)
 {
        EditBone *lastBone = NULL;
-       
        if ((scene->toolsettings->skgen_options & SKGEN_CUT_LENGTH) &&
-               arcLengthRatio(arc) >= scene->toolsettings->skgen_length_ratio)
+               arcLengthRatio(arc) >= G.scene->toolsettings->skgen_length_ratio)
        {
-               ReebArcIterator iter;
-               EmbedBucket *bucket = NULL;
-               EmbedBucket *previous = NULL;
-               EditBone *child = NULL;
-               EditBone *parent = NULL;
-               float lengthLimit = scene->toolsettings->skgen_length_limit;
-               int same = 0;
-               
-               parent = add_editbone(obedit, "Bone");
-               parent->flag |= BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-               VECCOPY(parent->head, head->p);
-
-               initArcIterator(&iter, arc, head);
-
-               bucket = nextBucket(&iter);
+               float invmat[4][4] = {  {1, 0, 0, 0},
+                                                               {0, 1, 0, 0},
+                                                               {0, 0, 1, 0},
+                                                               {0, 0, 0, 1}};
+               float tmat[3][3] = {    {1, 0, 0},
+                                                               {0, 1, 0},
+                                                               {0, 0, 1}};
+               ReebArcIterator arc_iter;
+               BArcIterator *iter = (BArcIterator*)&arc_iter;
+               bArmature *arm= obedit->data;
                
-               while (bucket != NULL)
-               {
-                       float *vec0 = NULL;
-                       float *vec1 = bucket->p;
-
-                       /* first bucket. Previous is head */
-                       if (previous == NULL)
-                       {
-                               vec0 = head->p;
-                       }
-                       /* Previous is a valid bucket */
-                       else
-                       {
-                               vec0 = previous->p;
-                       }
-                       
-                       /* If lengthLimit hits the current segment */
-                       if (VecLenf(vec1, parent->head) > lengthLimit)
-                       {
-                               if (same == 0)
-                               {
-                                       float dv[3], off[3];
-                                       float a, b, c, f;
-                                       
-                                       /* Solve quadratic distance equation */
-                                       VecSubf(dv, vec1, vec0);
-                                       a = Inpf(dv, dv);
-                                       
-                                       VecSubf(off, vec0, parent->head);
-                                       b = 2 * Inpf(dv, off);
-                                       
-                                       c = Inpf(off, off) - (lengthLimit * lengthLimit);
-                                       
-                                       f = (-b + (float)sqrt(b * b - 4 * a * c)) / (2 * a);
-                                       
-                                       //printf("a %f, b %f, c %f, f %f\n", a, b, c, f);
-                                       
-                                       if (isnan(f) == 0 && f < 1.0f)
-                                       {
-                                               VECCOPY(parent->tail, dv);
-                                               VecMulf(parent->tail, f);
-                                               VecAddf(parent->tail, parent->tail, vec0);
-                                       }
-                                       else
-                                       {
-                                               VECCOPY(parent->tail, vec1);
-                                       }
-                               }
-                               else
-                               {
-                                       float dv[3];
-                                       
-                                       VecSubf(dv, vec1, vec0);
-                                       Normalize(dv);
-                                        
-                                       VECCOPY(parent->tail, dv);
-                                       VecMulf(parent->tail, lengthLimit);
-                                       VecAddf(parent->tail, parent->tail, parent->head);
-                               }
-                               
-                               child = add_editbone(obedit, "Bone");
-                               VECCOPY(child->head, parent->tail);
-                               child->parent = parent;
-                               child->flag |= BONE_CONNECTED|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL;
-                               
-                               parent = child; // new child is next parent
-                               
-                               same = 1; // mark as same
-                       }
-                       else
-                       {
-                               previous = bucket;
-                               bucket = nextBucket(&iter);
-                               same = 0; // Reset same
-                       }
-               }
-               VECCOPY(parent->tail, tail->p);
+               initArcIterator(iter, arc, head);
                
-               lastBone = parent; /* set last bone in the chain */
+               lastBone = subdivideArcBy(arm, arm->edbo, iter, invmat, tmat, nextLengthSubdivision);
        }
        
        return lastBone;
@@ -5720,13 +5573,13 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg)
                        switch(scene->toolsettings->skgen_subdivisions[i])
                        {
                                case SKGEN_SUB_LENGTH:
-                                       lastBone = subdivideByLength(scene, obedit, arc, head, tail);
+                                       lastBone = test_subdivideByLength(scene, obedit, arc, head, tail);
                                        break;
                                case SKGEN_SUB_ANGLE:
                                        lastBone = subdivideByAngle(scene, obedit, arc, head, tail);
                                        break;
                                case SKGEN_SUB_CORRELATION:
-                                       lastBone = subdivideByCorrelation(scene, obedit, arc, head, tail);
+                                       lastBone = test_subdivideByCorrelation(scene, obedit, arc, head, tail);
                                        break;
                        }
                }