Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2007-08-11 15:50:31 +0400
committerJoshua Leung <aligorith@gmail.com>2007-08-11 15:50:31 +0400
commit4294de86100fa03b6b5ad494c6adee2b4aee6c6f (patch)
treed6d3aa83e9d355049ed28833449da9d47a403218 /source/blender/src/editarmature.c
parente8668988a31f700c330a05838ec949662458cc4e (diff)
Patch #7035 by Juho Vepsalainen (bebraw):
Multiple selected bones are now able to be parented to the active bone in EditMode. Previously, only one selected bone could be parented to another at a time.
Diffstat (limited to 'source/blender/src/editarmature.c')
-rw-r--r--source/blender/src/editarmature.c168
1 files changed, 91 insertions, 77 deletions
diff --git a/source/blender/src/editarmature.c b/source/blender/src/editarmature.c
index 61e6f2d9d37..b6d91242def 100644
--- a/source/blender/src/editarmature.c
+++ b/source/blender/src/editarmature.c
@@ -1815,95 +1815,108 @@ void show_all_armature_bones(void)
void make_bone_parent(void)
{
bArmature *arm= G.obedit->data;
- EditBone *ebone;
+ EditBone *actbone, *ebone, *selbone;
+ short foundselbone= 0, val;
float offset[3];
- short val;
-
- val= pupmenu("Make Parent%t|Connected%x1|Keep Offset%x2");
- if(val<1) return;
+ /* find active bone to parent to */
+ for (actbone = G.edbo.first; actbone; actbone=actbone->next) {
+ if (arm->layer & actbone->layer) {
+ if (actbone->flag & BONE_ACTIVE)
+ break;
+ }
+ }
+ if (actbone == NULL) {
+ error("Needs an active bone");
+ 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++;
+ }
+ }
+ }
+ /* abort if no selected bones, and active bone doesn't have a parent to work with instead */
+ if (foundselbone==0 && actbone->parent==NULL) {
+ error("Need selected bone(s)");
+ 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;
+ val= pupmenu("Make Parent%t|Connected%x1|Keep Offset%x2");
+ if (val < 1) return;
+
+ if (foundselbone==0 && actbone->parent) {
+ /* When only the active bone is selected, and it has a parent,
+ * connect it to the parent, as that is the only possible outcome.
+ */
+ actbone->flag |= BONE_CONNECTED;
+ VECCOPY(actbone->head, actbone->parent->tail);
+ actbone->rad_head= actbone->parent->rad_tail;
+ }
+ else {
+ /* loop through all editbones, parenting all selected bones to the active bone */
+ 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);
+
+ /* make actbone the parent of selbone */
+ 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);
-
- // 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;
+
+ if (val == 1) {
+ /* Connected: Child bones will be moved to the parent tip */
+ 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);
+
+ /* 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 {
+ /* Offset: Child bones will retain their distance from the parent tip */
+ 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)
@@ -3011,3 +3024,4 @@ void transform_armature_mirror_update(void)
}
}
+