[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13901] trunk/blender/source/blender/src/ editarmature.c: Bugfix:

Joshua Leung aligorith at gmail.com
Thu Feb 28 03:25:28 CET 2008


Revision: 13901
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13901
Author:   aligorith
Date:     2008-02-28 03:25:23 +0100 (Thu, 28 Feb 2008)

Log Message:
-----------
Bugfix:

Outliner drawing crashed after "Merge Bones" operation (Alt-M) if the end-bone of the merge had a child. 

Modified Paths:
--------------
    trunk/blender/source/blender/src/editarmature.c

Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c	2008-02-28 00:01:19 UTC (rev 13900)
+++ trunk/blender/source/blender/src/editarmature.c	2008-02-28 02:25:23 UTC (rev 13901)
@@ -121,7 +121,7 @@
 /* **************** tools on Editmode Armature **************** */
 
 /* converts Bones to EditBone list, used for tools as well */
-void make_boneList(ListBase* list, ListBase *bones, EditBone *parent)
+void make_boneList(ListBase *list, ListBase *bones, EditBone *parent)
 {
 	EditBone	*eBone;
 	Bone		*curBone;
@@ -131,7 +131,7 @@
 	float imat[3][3];
 	float difmat[3][3];
 		
-	for (curBone=bones->first; curBone; curBone=curBone->next){
+	for (curBone=bones->first; curBone; curBone=curBone->next) {
 		eBone= MEM_callocN(sizeof(EditBone), "make_editbone");
 		
 		/*	Copy relevant data from bone to eBone */
@@ -140,7 +140,7 @@
 		eBone->flag = curBone->flag;
 		
 		/* fix selection flags */
-		if(eBone->flag & BONE_SELECTED) {
+		if (eBone->flag & BONE_SELECTED) {
 			eBone->flag |= BONE_TIPSEL;
 			if(eBone->parent && (eBone->flag & BONE_CONNECTED))
 				eBone->parent->flag |= BONE_TIPSEL;
@@ -160,7 +160,7 @@
 		vec_roll_to_mat3(delta, 0.0, postmat);
 		
 		Mat3CpyMat4(premat, curBone->arm_mat);
-
+		
 		Mat3Inv(imat, postmat);
 		Mat3MulMat3(difmat, imat, premat);
 		
@@ -179,7 +179,7 @@
 		eBone->segments = curBone->segments;		
 		eBone->layer = curBone->layer;
 		
-		BLI_addtail (list, eBone);
+		BLI_addtail(list, eBone);
 		
 		/*	Add children if necessary */
 		if (curBone->childbase.first) 
@@ -210,7 +210,7 @@
 		
 		if (ebone) {
 			/* Get the ebone premat */
-			VecSubf (delta, ebone->tail, ebone->head);
+			VecSubf(delta, ebone->tail, ebone->head);
 			vec_roll_to_mat3(delta, ebone->roll, premat);
 			
 			/* Get the bone postmat */
@@ -220,9 +220,9 @@
 			Mat3MulMat3(difmat, imat, postmat);
 #if 0
 			printf ("Bone %s\n", curBone->name);
-			printmatrix4 ("premat", premat);
-			printmatrix4 ("postmat", postmat);
-			printmatrix4 ("difmat", difmat);
+			printmatrix4("premat", premat);
+			printmatrix4("postmat", postmat);
+			printmatrix4("difmat", difmat);
 			printf ("Roll = %f\n",  (-atan2(difmat[2][0], difmat[2][2]) * (180.0/M_PI)));
 #endif
 			curBone->roll = -atan2(difmat[2][0], difmat[2][2]);
@@ -230,7 +230,7 @@
 			/* and set restposition again */
 			where_is_armature_bone(curBone, curBone->parent);
 		}
-		fix_bonelist_roll (&curBone->childbase, editbonelist);
+		fix_bonelist_roll(&curBone->childbase, editbonelist);
 	}
 }
 
@@ -257,7 +257,7 @@
 			EditBone *fBone;
 			
 			/*	Find any bones that refer to this bone	*/
-			for (fBone=list->first; fBone; fBone= fBone->next){
+			for (fBone=list->first; fBone; fBone= fBone->next) {
 				if (fBone->parent==eBone)
 					fBone->parent= eBone->parent;
 			}
@@ -272,8 +272,8 @@
 		eBone->temp= newBone;	/* Associate the real Bones with the EditBones */
 		
 		BLI_strncpy (newBone->name, eBone->name, 32);
-		memcpy (newBone->head, eBone->head, sizeof(float)*3);
-		memcpy (newBone->tail, eBone->tail, sizeof(float)*3);
+		memcpy(newBone->head, eBone->head, sizeof(float)*3);
+		memcpy(newBone->tail, eBone->tail, sizeof(float)*3);
 		newBone->flag= eBone->flag;
 		if (eBone->flag & BONE_ACTIVE) 
 			newBone->flag |= BONE_SELECTED;	/* important, editbones can be active with only 1 point selected */
@@ -318,8 +318,8 @@
 				Mat3Inv(iM_parentRest, M_parentRest);
 				
 				/* Get the new head and tail */
-				VecSubf (newBone->head, eBone->head, eBone->parent->tail);
-				VecSubf (newBone->tail, eBone->tail, eBone->parent->tail);
+				VecSubf(newBone->head, eBone->head, eBone->parent->tail);
+				VecSubf(newBone->tail, eBone->tail, eBone->parent->tail);
 				
 				Mat3MulVecfl(iM_parentRest, newBone->head);
 				Mat3MulVecfl(iM_parentRest, newBone->tail);
@@ -332,7 +332,7 @@
 	
 	/* Make a pass through the new armature to fix rolling */
 	/* also builds restposition again (like where_is_armature) */
-	fix_bonelist_roll (&arm->bonebase, list);
+	fix_bonelist_roll(&arm->bonebase, list);
 	
 	/* so all users of this armature should get rebuilt */
 	for (obt= G.main->object.first; obt; obt= obt->id.next) {
@@ -1190,7 +1190,7 @@
 		bPoseChannel *chan, *next;
 		for (chan=G.obedit->pose->chanbase.first; chan; chan=next) {
 			next= chan->next;
-			curBone = editbone_name_exists (&G.edbo, chan->name);
+			curBone = editbone_name_exists(&G.edbo, chan->name);
 			
 			if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
 				free_constraints(&chan->constraints);
@@ -1321,11 +1321,9 @@
 
 void free_editArmature(void)
 {
-	
 	/*	Clear the editbones list */
-	if (G.edbo.first){
-		BLI_freelistN (&G.edbo);
-	}
+	if (G.edbo.first)
+		BLI_freelistN(&G.edbo);
 }
 
 void remake_editArmature(void)
@@ -1340,29 +1338,27 @@
 	allqueue(REDRAWBUTSOBJECT, 0);
 	
 //	BIF_undo_push("Delete bone");
-
 }
 
 /* Put object in EditMode */
 void make_editArmature(void)
 {
-	bArmature	*arm;
+	bArmature *arm;
 	
 	if (G.obedit==0) return;
 	
 	free_editArmature();
 	
 	arm= get_armature(G.obedit);
-	if (!arm)
-		return;
+	if (!arm) return;
 	
-	make_boneList (&G.edbo, &arm->bonebase,NULL);
+	make_boneList(&G.edbo, &arm->bonebase,NULL);
 }
 
 /* put EditMode back in Object */
 void load_editArmature(void)
 {
-	bArmature		*arm;
+	bArmature *arm;
 
 	arm= get_armature(G.obedit);
 	if (!arm) return;
@@ -1539,7 +1535,7 @@
 	
 	lb= MEM_callocN(sizeof(ListBase), "listbase undo");
 	
-	/* copy  */
+	/* copy */
 	for(ebo= G.edbo.first; ebo; ebo= ebo->next) {
 		newebo= MEM_dupallocN(ebo);
 		ebo->temp= newebo;
@@ -2200,7 +2196,7 @@
 /* this function merges between two bones, removes them and those in-between, 
  * and adjusts the parent relationships for those in-between
  */
-static void bones_merge(EditBone *start, EditBone *end, ListBase *chains)
+static void bones_merge(EditBone *start, EditBone *end, EditBone *endchild, ListBase *chains)
 {
 	EditBone *ebo, *ebone, *newbone;
 	LinkData *chain;
@@ -2230,11 +2226,11 @@
 		VECCOPY(tail, end->tail);
 	}
 	newbone= add_points_bone(head, tail);
-	newbone->parent = start->parent; 
+	newbone->parent = start->parent;
 	
-	/* step 2: parent children of in-between bones to newbone */
+	/* 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 */
+		/* ick: we need to check if parent of each bone in chain is one of the bones in the */
 		for (ebo= chain->data; ebo; ebo= ebo->parent) {
 			short found= 0;
 			
@@ -2254,6 +2250,10 @@
 		}
 	}
 	
+	/* step 2b: parent child of end to newbone (child from this chain) */
+	if (endchild)
+		endchild->parent= newbone;
+	
 	/* step 3: delete all bones between and including start and end */
 	for (ebo= end; ebo; ebo= ebone) {
 		ebone= (ebo == start) ? (NULL) : (ebo->parent);
@@ -2285,37 +2285,41 @@
 		/* each 'chain' is the last bone in the chain (with no children) */
 		for (chain= chains.first; chain; chain= nchain) {
 			EditBone *bstart= NULL, *bend= NULL;
+			EditBone *bchild= NULL, *child=NULL;
 			
 			/* temporarily remove chain from list of chains */
 			nchain= chain->next;
 			BLI_remlink(&chains, chain);
 			
 			/* only consider bones that are visible and selected */
-			for (ebo= chain->data; ebo; ebo= ebo->parent) {
+			for (ebo=chain->data; ebo; child=ebo, ebo=ebo->parent) {
 				/* check if visible + selected */
 				if ( (arm->layer & ebo->layer) && !(ebo->flag & BONE_HIDDEN_A) &&
 					 ((ebo->flag & BONE_CONNECTED) || (ebo->parent==NULL)) &&
 					 (ebo->flag & (BONE_SELECTED|BONE_ACTIVE)) )
 				{
 					/* set either end or start (end gets priority, unless it is already set) */
-					if (bend == NULL) 
+					if (bend == NULL)  {
 						bend= ebo;
+						bchild= child;
+					}
 					else 
 						bstart= ebo;
 				}
 				else {
 					/* chain is broken... merge any continous segments then clear */
 					if (bstart && bend)
-						bones_merge(bstart, bend, &chains);
+						bones_merge(bstart, bend, bchild, &chains);
 					
 					bstart = NULL;
 					bend = NULL;
+					bchild = NULL;
 				}
 			}
 			
 			/* merge from bstart to bend if something not merged */
 			if (bstart && bend)
-				bones_merge(bstart, bend, &chains);
+				bones_merge(bstart, bend, bchild, &chains);
 			
 			/* put back link */
 			BLI_insertlinkbefore(&chains, nchain, chain);





More information about the Bf-blender-cvs mailing list