[Bf-blender-cvs] [c0be69f] master: Fix/Improve FKey bone creation

Campbell Barton noreply at git.blender.org
Fri Mar 20 13:49:15 CET 2015


Commit: c0be69f7fdb8f905f6133663e6f91a0d849b7795
Author: Campbell Barton
Date:   Fri Mar 20 23:38:08 2015 +1100
Branches: master
https://developer.blender.org/rBc0be69f7fdb8f905f6133663e6f91a0d849b7795

Fix/Improve FKey bone creation

- new bone is now made active
- previous selection cleared
- bone direction places the tip on the active bone (if available)

===================================================================

M	source/blender/editors/armature/armature_edit.c

===================================================================

diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 88c5298..6fe4cbf 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -578,6 +578,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
 	Scene *scene = CTX_data_scene(C);
 	View3D *v3d = CTX_wm_view3d(C);
 	ListBase points = {NULL, NULL};
+	EditBone *newbone = NULL;
 	int count;
 
 	/* sanity checks */
@@ -610,94 +611,97 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
 		float curs[3];
 		
 		/* Get Points - selected joint */
-		ebp = (EditBonePoint *)points.first;
+		ebp = points.first;
 		
 		/* Get points - cursor (tail) */
 		invert_m4_m4(obedit->imat, obedit->obmat);
 		mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
 		
 		/* Create a bone */
-		/* newbone = */ add_points_bone(obedit, ebp->vec, curs);
+		newbone = add_points_bone(obedit, ebp->vec, curs);
 	}
 	else if (count == 2) {
-		EditBonePoint *ebp, *ebp2;
+		EditBonePoint *ebp_a, *ebp_b;
 		float head[3], tail[3];
 		short headtail = 0;
 		
 		/* check that the points don't belong to the same bone */
-		ebp = (EditBonePoint *)points.first;
-		ebp2 = ebp->next;
+		ebp_a = (EditBonePoint *)points.first;
+		ebp_b = ebp_a->next;
 		
-		if ((ebp->head_owner == ebp2->tail_owner) && (ebp->head_owner != NULL)) {
-			BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
-			BLI_freelistN(&points);
-			return OPERATOR_CANCELLED;
-		}
-		if ((ebp->tail_owner == ebp2->head_owner) && (ebp->tail_owner != NULL)) {
+		if (((ebp_a->head_owner == ebp_b->tail_owner) && (ebp_a->head_owner != NULL)) ||
+		    ((ebp_a->tail_owner == ebp_b->head_owner) && (ebp_a->tail_owner != NULL)))
+		{
 			BKE_report(op->reports, RPT_ERROR, "Same bone selected...");
 			BLI_freelistN(&points);
 			return OPERATOR_CANCELLED;
 		}
 		
 		/* find which one should be the 'head' */
-		if ((ebp->head_owner && ebp2->head_owner) || (ebp->tail_owner && ebp2->tail_owner)) {
-			/* rule: whichever one is closer to 3d-cursor */
-			float curs[3];
-			float vecA[3], vecB[3];
-			float distA, distB;
-			
-			/* get cursor location */
-			invert_m4_m4(obedit->imat, obedit->obmat);
-			mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
-			
-			/* get distances */
-			sub_v3_v3v3(vecA, ebp->vec, curs);
-			sub_v3_v3v3(vecB, ebp2->vec, curs);
-			distA = len_v3(vecA);
-			distB = len_v3(vecB);
-			
-			/* compare distances - closer one therefore acts as direction for bone to go */
-			headtail = (distA < distB) ? 2 : 1;
+		if ((ebp_a->head_owner && ebp_b->head_owner) || (ebp_a->tail_owner && ebp_b->tail_owner)) {
+			/* use active, nice predictable */
+			if (arm->act_edbone && ELEM(arm->act_edbone, ebp_a->head_owner, ebp_a->tail_owner)) {
+				headtail = 1;
+			}
+			else if (arm->act_edbone && ELEM(arm->act_edbone, ebp_b->head_owner, ebp_b->tail_owner)) {
+				headtail = 2;
+			}
+			else {
+				/* rule: whichever one is closer to 3d-cursor */
+				float curs[3];
+				float dist_sq_a, dist_sq_b;
+
+				/* get cursor location */
+				invert_m4_m4(obedit->imat, obedit->obmat);
+				mul_v3_m4v3(curs, obedit->imat, ED_view3d_cursor3d_get(scene, v3d));
+
+				/* get distances */
+				dist_sq_a = len_squared_v3v3(ebp_a->vec, curs);
+				dist_sq_b = len_squared_v3v3(ebp_b->vec, curs);
+
+				/* compare distances - closer one therefore acts as direction for bone to go */
+				headtail = (dist_sq_a < dist_sq_b) ? 2 : 1;
+			}
 		}
-		else if (ebp->head_owner) {
+		else if (ebp_a->head_owner) {
 			headtail = 1;
 		}
-		else if (ebp2->head_owner) {
+		else if (ebp_b->head_owner) {
 			headtail = 2;
 		}
 		
 		/* assign head/tail combinations */
 		if (headtail == 2) {
-			copy_v3_v3(head, ebp->vec);
-			copy_v3_v3(tail, ebp2->vec);
+			copy_v3_v3(head, ebp_a->vec);
+			copy_v3_v3(tail, ebp_b->vec);
 		}
 		else if (headtail == 1) {
-			copy_v3_v3(head, ebp2->vec);
-			copy_v3_v3(tail, ebp->vec);
+			copy_v3_v3(head, ebp_b->vec);
+			copy_v3_v3(tail, ebp_a->vec);
 		}
 		
 		/* add new bone and parent it to the appropriate end */
 		if (headtail) {
-			EditBone *newbone = add_points_bone(obedit, head, tail);
+			newbone = add_points_bone(obedit, head, tail);
 			
 			/* do parenting (will need to set connected flag too) */
 			if (headtail == 2) {
 				/* ebp tail or head - tail gets priority */
-				if (ebp->tail_owner)
-					newbone->parent = ebp->tail_owner;
+				if (ebp_a->tail_owner)
+					newbone->parent = ebp_a->tail_owner;
 				else
-					newbone->parent = ebp->head_owner;
+					newbone->parent = ebp_a->head_owner;
 			}
 			else {
-				/* ebp2 tail or head - tail gets priority */
-				if (ebp2->tail_owner)
-					newbone->parent = ebp2->tail_owner;
+				/* ebp_b tail or head - tail gets priority */
+				if (ebp_b->tail_owner)
+					newbone->parent = ebp_b->tail_owner;
 				else
-					newbone->parent = ebp2->head_owner;
+					newbone->parent = ebp_b->head_owner;
 			}
 
 			/* don't set for bone connecting two head points of bones */
-			if (ebp->tail_owner || ebp2->tail_owner) {
+			if (ebp_a->tail_owner || ebp_b->tail_owner) {
 				newbone->flag |= BONE_CONNECTED;
 			}
 		}
@@ -708,6 +712,12 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op)
 		BLI_freelistN(&points);
 		return OPERATOR_CANCELLED;
 	}
+
+	if (newbone) {
+		ED_armature_deselect_all(obedit, 0);
+		arm->act_edbone = newbone;
+		newbone->flag |= BONE_TIPSEL;
+	}
 	
 	/* updates */
 	WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);




More information about the Bf-blender-cvs mailing list