[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11477] trunk/blender/source/blender: == Bone Roll - Align to Cursor ==

Joshua Leung aligorith at gmail.com
Fri Aug 3 13:16:12 CEST 2007


Revision: 11477
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11477
Author:   aligorith
Date:     2007-08-03 13:16:12 +0200 (Fri, 03 Aug 2007)

Log Message:
-----------
== Bone Roll - Align to Cursor ==

In this commit, a new way to set the bone roll is introduced. It aligns the z-axis of the selected bone(s) to the 3D-Cursor, so that the cursor intersects with the YZ plane. 

This makes it easier to align bone rolls to a target, for use in rigs where arms/legs are not horizontal/vertical. To use this, just press Ctrl N, and choose the "Align Z-Axis to 3D-Cursor" option.

Credits go to Robert Christian (wavez) for providing the method as a working BPy script, that demonstrated this in action.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BIF_editarmature.h
    trunk/blender/source/blender/src/drawview.c
    trunk/blender/source/blender/src/editarmature.c
    trunk/blender/source/blender/src/header_view3d.c
    trunk/blender/source/blender/src/space.c

Modified: trunk/blender/source/blender/include/BIF_editarmature.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editarmature.h	2007-08-03 04:04:00 UTC (rev 11476)
+++ trunk/blender/source/blender/include/BIF_editarmature.h	2007-08-03 11:16:12 UTC (rev 11477)
@@ -106,9 +106,9 @@
 void	selectconnected_armature(void);
 void	selectconnected_posearmature(void);
 void	select_bone_parent(void);
-void    unique_editbone_name (struct ListBase *ebones, char* name);
+void    unique_editbone_name (struct ListBase *ebones, char *name);
 
-void	auto_align_armature(void);
+void	auto_align_armature(short mode);
 void	create_vgroups_from_armature(Object *ob, Object *par);
 
 void	hide_selected_pose_bones(void);

Modified: trunk/blender/source/blender/src/drawview.c
===================================================================
--- trunk/blender/source/blender/src/drawview.c	2007-08-03 04:04:00 UTC (rev 11476)
+++ trunk/blender/source/blender/src/drawview.c	2007-08-03 11:16:12 UTC (rev 11477)
@@ -1866,7 +1866,6 @@
 	}
 }
 
-
 static void v3d_posearmature_buts(uiBlock *block, Object *ob, float lim)
 {
 	uiBut *but;
@@ -1954,9 +1953,9 @@
 	uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipY:",	160, 50, 140, 19, ebone->tail+1, -lim, lim, 10, 3, "");
 	uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipZ:",	160, 30, 140, 19, ebone->tail+2, -lim, lim, 10, 3, "");
 	uiBlockEndAlign(block);
+	
 	tfp->ob_eul[0]= 180.0*ebone->roll/M_PI;
 	uiDefButF(block, NUM, B_ARMATUREPANEL1, "Roll:",	10, 100, 140, 19, tfp->ob_eul, -lim, lim, 1000, 3, "");
-	
 
 	uiBlockBeginAlign(block);
 	uiDefButF(block, NUM, B_ARMATUREPANEL1, "TipRadius:",	10, 150, 140, 19, &ebone->rad_tail, 0, lim, 10, 3, "");

Modified: trunk/blender/source/blender/src/editarmature.c
===================================================================
--- trunk/blender/source/blender/src/editarmature.c	2007-08-03 04:04:00 UTC (rev 11476)
+++ trunk/blender/source/blender/src/editarmature.c	2007-08-03 11:16:12 UTC (rev 11477)
@@ -1269,37 +1269,80 @@
 	}
 }
 
-void auto_align_armature(void)
-/* Sets the roll value of selected bones so that their zaxes point upwards */
+/* Sets the roll value of selected bones, depending on the mode
+ * 	mode == 0: their z-axes point upwards 
+ * 	mode == 1: their z-axes point towards 3d-cursor
+ */
+void auto_align_armature(short mode)
 {
 	bArmature *arm= G.obedit->data;
 	EditBone *ebone;
-	float	xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
-	float	targetmat[3][3], imat[3][3];
-	float	curmat[3][3], diffmat[3][3];
 	float	delta[3];
-	
-	for (ebone = G.edbo.first; ebone; ebone=ebone->next){
+	float	curmat[3][3];
+	float  	*cursor= give_cursor();
+		
+	for (ebone = G.edbo.first; ebone; ebone=ebone->next) {
 		if(arm->layer & ebone->layer) {
-			if (ebone->flag & BONE_SELECTED){
-				/* Find the current bone matrix */
-				VecSubf(delta, ebone->tail, ebone->head);
-				vec_roll_to_mat3(delta, 0.0, curmat);
-				
-				/* Make new matrix based on y axis & z-up */
-				VECCOPY (yaxis, curmat[1]);
-				
-				Mat3One(targetmat);
-				VECCOPY (targetmat[0], xaxis);
-				VECCOPY (targetmat[1], yaxis);
-				VECCOPY (targetmat[2], zaxis);
-				Mat3Ortho(targetmat);
-				
-				/* Find the difference between the two matrices */
-				Mat3Inv(imat, targetmat);
-				Mat3MulMat3(diffmat, imat, curmat);
-				
-				ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
+			if (ebone->flag & BONE_SELECTED) {
+				/* specific method used to calculate roll depends on mode */
+				if (mode == 1) {
+					/* Z-Axis point towards cursor */
+					float	mat[4][4], tmat[4][4], imat[4][4];
+					float 	rmat[4][4], rot[3];
+					float	vec[3];
+					
+					/* find the current bone matrix as a 4x4 matrix (in Armature Space) */
+					VecSubf(delta, ebone->tail, ebone->head);
+					vec_roll_to_mat3(delta, ebone->roll, curmat);
+					Mat4CpyMat3(mat, curmat);
+					VECCOPY(mat[3], ebone->head);
+					
+					/* multiply bone-matrix by object matrix (so that bone-matrix is in WorldSpace) */
+					Mat4MulMat4(tmat, mat, G.obedit->obmat);
+					Mat4Invert(imat, tmat);
+					
+					/* find position of cursor relative to bone */
+					VecMat4MulVecfl(vec, imat, cursor);
+					
+					/* check that cursor is in usable position */
+					if ((IS_EQ(vec[0], 0)==0) && (IS_EQ(vec[2], 0)==0)) {
+						/* Compute a rotation matrix around y */
+						rot[1] = atan2(vec[0], vec[2]);
+						rot[0] = rot[2] = 0.0f;
+						EulToMat4(rot, rmat);
+						
+						/* Multiply the bone matrix by rotation matrix. This should be new bone-matrix */
+						Mat4MulMat4(tmat, rmat, mat);
+						Mat3CpyMat4(curmat, tmat);
+						
+						/* Now convert from new bone-matrix, back to a roll value (in radians) */
+						mat3_to_vec_roll(curmat, delta, &ebone->roll);
+					}
+				}
+				else { 
+					/* Z-Axis Point Up */
+					float	xaxis[3]={1.0, 0.0, 0.0}, yaxis[3], zaxis[3]={0.0, 0.0, 1.0};
+					float	targetmat[3][3], imat[3][3], diffmat[3][3];
+					
+					/* Find the current bone matrix */
+					VecSubf(delta, ebone->tail, ebone->head);
+					vec_roll_to_mat3(delta, 0.0, curmat);
+					
+					/* Make new matrix based on y axis & z-up */
+					VECCOPY (yaxis, curmat[1]);
+					
+					Mat3One(targetmat);
+					VECCOPY (targetmat[0], xaxis);
+					VECCOPY (targetmat[1], yaxis);
+					VECCOPY (targetmat[2], zaxis);
+					Mat3Ortho(targetmat);
+					
+					/* Find the difference between the two matrices */
+					Mat3Inv(imat, targetmat);
+					Mat3MulMat3(diffmat, imat, curmat);
+					
+					ebone->roll = atan2(diffmat[2][0], diffmat[2][2]);
+				}
 			}
 		}
 	}

Modified: trunk/blender/source/blender/src/header_view3d.c
===================================================================
--- trunk/blender/source/blender/src/header_view3d.c	2007-08-03 04:04:00 UTC (rev 11476)
+++ trunk/blender/source/blender/src/header_view3d.c	2007-08-03 11:16:12 UTC (rev 11477)
@@ -3633,6 +3633,39 @@
 	return block;
 }
 
+void do_view3d_edit_armature_rollmenu(void *arg, int event)
+{
+	if (event == 1 || event == 2)
+		/* set roll based on aligning z-axis */
+		auto_align_armature(event);
+	else if (event == 3) {
+		/* interactively set bone roll */
+		initTransform(TFM_BONE_ROLL, CTX_NONE);
+		Transform();
+	}
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+static uiBlock *view3d_edit_armature_rollmenu(void *arg_unused)
+{
+	uiBlock *block;
+	short yco = 20, menuwidth = 120;
+
+	block= uiNewBlock(&curarea->uiblocks, "view3d_edit_armature_rollmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+	uiBlockSetButmFunc(block, do_view3d_edit_armature_rollmenu, NULL);
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Roll (Z-Axis Up)|Ctrl N, 1",	0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Roll to Cursor|Ctrl N, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+	
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Roll|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
+	
+	uiBlockSetDirection(block, UI_RIGHT);
+	uiTextBoundsBlock(block, 60);
+	return block;
+}
+
 static void do_view3d_edit_armaturemenu(void *arg, int event)
 {
 	switch(event) {
@@ -3662,18 +3695,12 @@
 	case 10: /* forked! */
 		extrude_armature(1);
 		break;
-	case 11: /* clear roll */
-		auto_align_armature();
-		break;
 	case 12: /* subdivide */
 		subdivide_armature();
 		break;
 	case 13: /* flip left and right names */
 		armature_flip_names();
 		break;
-	case 14: /* interactively set bone roll */
-		initTransform(TFM_BONE_ROLL, CTX_NONE);
-		Transform();
 	}
 	allqueue(REDRAWVIEW3D, 0);
 }
@@ -3729,8 +3756,7 @@
 	uiDefIconTextBlockBut(block, view3d_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
 	uiDefIconTextBlockBut(block, view3d_edit_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, menuwidth, 19, "");
 	uiDefIconTextBlockBut(block, view3d_edit_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Set Bone Roll Angle|Ctrl R",		0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 14, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Bone Roll Angle|Ctrl N",		0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
+	uiDefIconTextBlockBut(block, view3d_edit_armature_rollmenu, NULL, ICON_RIGHTARROW_THIN, "Bone Roll", 0, yco-=20, 120, 19, "");
 	
 	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 

Modified: trunk/blender/source/blender/src/space.c
===================================================================
--- trunk/blender/source/blender/src/space.c	2007-08-03 04:04:00 UTC (rev 11476)
+++ trunk/blender/source/blender/src/space.c	2007-08-03 11:16:12 UTC (rev 11477)
@@ -2080,9 +2080,10 @@
 				else if(G.obedit) {
 					switch (G.obedit->type){
 					case OB_ARMATURE:
-						if(G.qual==LR_CTRLKEY){
-							if (okee("Recalculate bone roll angles")) {
-								auto_align_armature();
+						if(G.qual==LR_CTRLKEY) {
+							pupval= pupmenu("Recalculate Bone Roll Angles%t|Clear Roll (Z-Axis Up) %x1|Align Z-Axis to 3D-Cursor %x2");
+							if (pupval > 0) {
+								auto_align_armature(pupval - 1);
 								allqueue(REDRAWVIEW3D, 0);
 							}
 						}





More information about the Bf-blender-cvs mailing list