diff options
Diffstat (limited to 'source/blender/editors/armature/editarmature.c')
-rw-r--r-- | source/blender/editors/armature/editarmature.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 08f313bfadd..eaaaa12eca1 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -3008,28 +3006,31 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone /* TODO, copy more things to the new bone */ newbone->flag= start->flag & (BONE_HINGE|BONE_NO_DEFORM|BONE_NO_SCALE|BONE_NO_CYCLICOFFSET|BONE_NO_LOCAL_LOCATION|BONE_DONE); - /* step 2a: parent children of in-between bones to newbone */ - for (chain= chains->first; chain; chain= chain->next) { - /* ick: we need to check if parent of each bone in chain is one of the bones in the */ - short found= 0; - for (ebo= chain->data; ebo; ebo= ebo->parent) { + /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge + * - potentially several tips for side chains leading to some tree exist... + */ + for (chain = chains->first; chain; chain = chain->next) { + /* traverse down chain until we hit the bottom or if we run into the tip of the chain of bones we're + * merging (need to stop in this case to avoid corrupting this chain too!) + */ + for (ebone = chain->data; (ebone) && (ebone != end); ebone = ebone->parent) { + short found = 0; - /* try to find which bone from the list to be removed, is the parent */ - for (ebone= end; ebone; ebone= ebone->parent) { - if (ebo->parent == ebone) { - found= 1; + /* check if this bone is parented to one in the merging chain + * ! WATCHIT: must only go check until end of checking chain + */ + for (ebo = end; (ebo) && (ebo != start->parent); ebo = ebo->parent) { + /* side-chain found? --> remap parent to new bone, then we're done with this chain :) */ + if (ebone->parent == ebo) { + ebone->parent = newbone; + found = 1; break; } } - /* adjust this bone's parent to newbone then */ - if (found) { - ebo->parent= newbone; + /* carry on to the next tip now */ + if (found) break; - } - } - if (found) { - break; } } @@ -3065,12 +3066,12 @@ static int armature_merge_exec (bContext *C, wmOperator *op) LinkData *chain, *nchain; EditBone *ebo; + armature_tag_select_mirrored(arm); + /* get chains (ends on chains) */ chains_find_tips(arm->edbo, &chains); if (chains.first == NULL) return OPERATOR_CANCELLED; - - armature_tag_select_mirrored(arm); - + /* each 'chain' is the last bone in the chain (with no children) */ for (chain= chains.first; chain; chain= nchain) { EditBone *bstart= NULL, *bend= NULL; @@ -3115,7 +3116,7 @@ static int armature_merge_exec (bContext *C, wmOperator *op) } armature_tag_unselect(arm); - + BLI_freelistN(&chains); } |