[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38604] branches/soc-2011-pepper/source/ blender/editors/armature/editarmature.c: Bugfix [#27990] Merge Bones freezes Blender

Joshua Leung aligorith at gmail.com
Fri Jul 22 15:52:32 CEST 2011


Revision: 38604
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38604
Author:   aligorith
Date:     2011-07-22 13:52:31 +0000 (Fri, 22 Jul 2011)
Log Message:
-----------
Bugfix [#27990] Merge Bones freezes Blender

Recoded side-chain reparenting step to fix (as far as I've been able
to tell) infinite looping problems which were a bit intermittent here
using the test file. The fix here involves some tighter checks to
prevent corrupting the parenting of bones in the run of bones being
merged but also of any ancestors of those.

Modified Paths:
--------------
    branches/soc-2011-pepper/source/blender/editors/armature/editarmature.c

Modified: branches/soc-2011-pepper/source/blender/editors/armature/editarmature.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/armature/editarmature.c	2011-07-22 11:53:20 UTC (rev 38603)
+++ branches/soc-2011-pepper/source/blender/editors/armature/editarmature.c	2011-07-22 13:52:31 UTC (rev 38604)
@@ -2993,29 +2993,32 @@
 	/* 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 chain being merged */
-		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;
-		}
 	}
 	
 	/* step 2b: parent child of end to newbone (child from this chain) */
@@ -3050,12 +3053,12 @@
 		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;
@@ -3100,7 +3103,7 @@
 		}		
 		
 		armature_tag_unselect(arm);
-
+		
 		BLI_freelistN(&chains);
 	}
 	




More information about the Bf-blender-cvs mailing list