Index: source/blender/src/editarmature.c =================================================================== --- source/blender/src/editarmature.c (revision 11544) +++ source/blender/src/editarmature.c (working copy) @@ -1815,95 +1815,98 @@ void make_bone_parent(void) { bArmature *arm= G.obedit->data; - EditBone *ebone; + EditBone *actbone, *ebone, *selbone; float offset[3]; + short allchildbones= 1; + short foundselbone= 0; short val; + char str[64]= "Make Parent%t|Connected%x1"; + + /* find active bone */ + for (actbone = G.edbo.first; actbone; actbone=actbone->next) + if(arm->layer & actbone->layer) + if(actbone->flag & BONE_ACTIVE) break; - val= pupmenu("Make Parent%t|Connected%x1|Keep Offset%x2"); + if(!actbone) return; + + /* find selected bones */ + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + if(arm->layer & ebone->layer) { + if((ebone->flag & BONE_SELECTED) && (ebone!=actbone)) { + foundselbone= 1; + if(ebone->parent != actbone) allchildbones= 0; + } + } + } + if(!foundselbone && !actbone->parent) return; + + if(!allchildbones) strcat(str, "|Keep Offset%x2"); + + val= pupmenu(str); + if(val<1) return; - - /* find active */ - for (ebone = G.edbo.first; ebone; ebone=ebone->next) - if(arm->layer & ebone->layer) - if(ebone->flag & BONE_ACTIVE) break; - - if(ebone) { - EditBone *actbone= ebone, *selbone= NULL; - - /* find selected */ - for (ebone = G.edbo.first; ebone; ebone=ebone->next) { - if(arm->layer & ebone->layer) { - if(ebone->flag & BONE_SELECTED) { - if(ebone!=actbone) { - if(selbone==NULL) selbone= ebone; - else { - error("Need one active and one selected bone"); - return; + + if(!foundselbone && actbone->parent) { + actbone->flag |= BONE_CONNECTED; + VECCOPY(actbone->head, actbone->parent->tail); + actbone->rad_head= actbone->parent->rad_tail; + } + else { + for (selbone = G.edbo.first; selbone; selbone=selbone->next) { + if(arm->layer & selbone->layer) { + if((selbone->flag & BONE_SELECTED) && (selbone!=actbone)) { + /* if selbone had a parent we clear parent tip */ + if(selbone->parent && (selbone->flag & BONE_CONNECTED)) + selbone->parent->flag &= ~(BONE_TIPSEL); + + selbone->parent= actbone; + + /* in actbone tree we cannot have a loop */ + for(ebone= actbone->parent; ebone; ebone= ebone->parent) { + if(ebone->parent==selbone) { + ebone->parent= NULL; + ebone->flag &= ~BONE_CONNECTED; } } - } - } - } - if(selbone==NULL) { - /* we make sure bone is connected */ - if(val==1 && actbone->parent) { - actbone->flag |= BONE_CONNECTED; - VECCOPY(actbone->head, actbone->parent->tail); - actbone->rad_head= actbone->parent->rad_tail; - countall(); // checks selection - allqueue(REDRAWVIEW3D, 0); - BIF_undo_push("Connect to Parent"); - } - else error("Need one active and one selected bone"); - } - else { - /* if selbone had a parent we clear parent tip */ - if(selbone->parent && (selbone->flag & BONE_CONNECTED)) - selbone->parent->flag &= ~(BONE_TIPSEL); - - selbone->parent= actbone; - - /* in actbone tree we cannot have a loop */ - for(ebone= actbone->parent; ebone; ebone= ebone->parent) { - if(ebone->parent==selbone) { - ebone->parent= NULL; - ebone->flag &= ~BONE_CONNECTED; - } - } - - if(val==1) { // connected - selbone->flag |= BONE_CONNECTED; - VecSubf(offset, actbone->tail, selbone->head); - - VECCOPY(selbone->head, actbone->tail); - selbone->rad_head= actbone->rad_tail; - VecAddf(selbone->tail, selbone->tail, offset); + if(val==1) { /* connected */ + selbone->flag |= BONE_CONNECTED; + VecSubf(offset, actbone->tail, selbone->head); + + VECCOPY(selbone->head, actbone->tail); + selbone->rad_head= actbone->rad_tail; - // offset for all its children - for (ebone = G.edbo.first; ebone; ebone=ebone->next) { - EditBone *par; - for(par= ebone->parent; par; par= par->parent) { - if(par==selbone) { - VecAddf(ebone->head, ebone->head, offset); - VecAddf(ebone->tail, ebone->tail, offset); - break; + VecAddf(selbone->tail, selbone->tail, offset); + + /* offset for all its children */ + for (ebone = G.edbo.first; ebone; ebone=ebone->next) { + EditBone *par; + + for(par= ebone->parent; par; par= par->parent) { + if(par==selbone) { + VecAddf(ebone->head, ebone->head, offset); + VecAddf(ebone->tail, ebone->tail, offset); + break; + } + } } } + else { + selbone->flag &= ~BONE_CONNECTED; + } } } - else { - selbone->flag &= ~BONE_CONNECTED; - } - - countall(); // checks selection - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWBUTSEDIT, 0); - allqueue(REDRAWOOPS, 0); - BIF_undo_push("Make Parent"); } } + + countall(); /* checks selection */ + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWOOPS, 0); + BIF_undo_push("Make Parent"); + + return; } void clear_bone_parent(void)