Index: source/blender/include/BIF_editarmature.h =================================================================== --- source/blender/include/BIF_editarmature.h (revision 10841) +++ source/blender/include/BIF_editarmature.h (working copy) @@ -85,7 +85,7 @@ void deselectall_posearmature (struct Object *ob, int test, int doundo); int draw_armature(struct Base *base, int dt); void extrude_armature(int forked); -void subdivide_armature(void); +void subdivide_armature(int numcuts); void free_editArmature(void); Index: source/blender/src/editarmature.c =================================================================== --- source/blender/src/editarmature.c (revision 10841) +++ source/blender/src/editarmature.c (working copy) @@ -2051,53 +2051,74 @@ } /* context; editmode armature */ -void subdivide_armature(void) +void subdivide_armature(int numcuts) { bArmature *arm= G.obedit->data; EditBone *ebone, *newbone, *tbone, *mbone; - int a; + int a, i; + if(numcuts < 1) return; + for (mbone = G.edbo.last; mbone; mbone= mbone->prev) { if(arm->layer & mbone->layer) { if(mbone->flag & BONE_SELECTED) { - /* take care of mirrored stuff */ - for(a=0; a<2; a++) { - if(a==0) ebone= mbone; - else { - if(arm->flag & ARM_MIRROR_EDIT) - ebone= armature_bone_get_mirrored(mbone); - else ebone= NULL; - } - if(ebone) { - - newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv"); - *newbone = *ebone; - BLI_addtail(&G.edbo, newbone); + for(i=numcuts+1; i>1; i--) { + /* take care of mirrored stuff */ + for(a=0; a<2; a++) { + float cutratio; + float val1[3]; + float val2[3]; + float val3[3]; - VecMidf(newbone->head, ebone->head, ebone->tail); - VECCOPY(newbone->tail, ebone->tail); - VECCOPY(ebone->tail, newbone->head); - - newbone->rad_head= 0.5*(ebone->rad_head+ebone->rad_tail); - ebone->rad_tail= newbone->rad_head; - - newbone->flag |= BONE_CONNECTED; - - unique_editbone_name (&G.edbo, newbone->name); - - /* correct parent bones */ - for (tbone = G.edbo.first; tbone; tbone=tbone->next){ - if(tbone->parent==ebone) - tbone->parent= newbone; + if(a==0) ebone= mbone; + else { + if(arm->flag & ARM_MIRROR_EDIT) + ebone= armature_bone_get_mirrored(mbone); + else ebone= NULL; } - newbone->parent= ebone; + if(ebone) { + + newbone= MEM_mallocN(sizeof(EditBone), "ebone subdiv"); + *newbone = *ebone; + BLI_addtail(&G.edbo, newbone); + + /* calculate location of newbone->head */ + VECCOPY(val1, ebone->head); + VECCOPY(val2, ebone->tail); + VECCOPY(val3, newbone->head); + + cutratio= 1/(float)i; + val3[0]= val1[0]*cutratio+val2[0]*(1-cutratio); + val3[1]= val1[1]*cutratio+val2[1]*(1-cutratio); + val3[2]= val1[2]*cutratio+val2[2]*(1-cutratio); + + VECCOPY(newbone->head, val3); + VECCOPY(newbone->tail, ebone->tail); + VECCOPY(ebone->tail, newbone->head); + + newbone->rad_head= 0.5*(ebone->rad_head+ebone->rad_tail); + ebone->rad_tail= newbone->rad_head; + + newbone->flag |= BONE_CONNECTED; + + unique_editbone_name (&G.edbo, newbone->name); + + /* correct parent bones */ + for (tbone = G.edbo.first; tbone; tbone=tbone->next){ + if(tbone->parent==ebone) + tbone->parent= newbone; + } + newbone->parent= ebone; + } } } } } } - BIF_undo_push("Subdivide"); + + if(numcuts==1) BIF_undo_push("Subdivide"); + else BIF_undo_push("Subdivide multi"); } /* ***************** Pose tools ********************* */ Index: source/blender/src/header_view3d.c =================================================================== --- source/blender/src/header_view3d.c (revision 10841) +++ source/blender/src/header_view3d.c (working copy) @@ -3598,6 +3598,8 @@ static void do_view3d_edit_armaturemenu(void *arg, int event) { + static short numcuts= 2; + switch(event) { case 0: /* Undo Editing */ @@ -3629,7 +3631,7 @@ auto_align_armature(); break; case 12: /* subdivide */ - subdivide_armature(); + subdivide_armature(1); break; case 13: /* flip left and right names */ armature_flip_names(); @@ -3637,6 +3639,11 @@ case 14: /* interactively set bone roll */ initTransform(TFM_BONE_ROLL, CTX_NONE); Transform(); + break; + case 15: /* subdivide multi */ + if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; + waitcursor(1); + subdivide_armature(numcuts); } allqueue(REDRAWVIEW3D, 0); } @@ -3707,7 +3714,8 @@ uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide|W, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, ""); - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Left & Right Names|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Subdivide Multi|W, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 15, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Left & Right Names|W, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); Index: source/blender/src/editobject.c =================================================================== --- source/blender/src/editobject.c (revision 10841) +++ source/blender/src/editobject.c (working copy) @@ -2490,10 +2490,15 @@ DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA); } else if(G.obedit->type==OB_ARMATURE) { - nr= pupmenu("Specials%t|Subdivide %x1|Flip Left-Right Names%x2"); + nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Flip Left-Right Names%x2"); if(nr==1) - subdivide_armature(); - else if(nr==2) + subdivide_armature(1); + if(nr==2) { + if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; + waitcursor(1); + subdivide_armature(numcuts); + } + else if(nr==3) armature_flip_names(); } else if(G.obedit->type==OB_LATTICE) {