[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33958] trunk/blender/source/blender/ editors/space_view3d/view3d_select.c: Bugfix [#25415] Circle Selection does not work on bones in Pose mode

Joshua Leung aligorith at gmail.com
Fri Dec 31 04:35:37 CET 2010


Revision: 33958
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33958
Author:   aligorith
Date:     2010-12-31 04:35:34 +0100 (Fri, 31 Dec 2010)

Log Message:
-----------
Bugfix [#25415] Circle Selection does not work on bones in Pose mode

Clobbered together some new code to do this based on the code for Edit
Bone circle select as this case doesn't seem to have been implemented
yet.

NOTE: the code in view3d_select.c needs some urgent love and tidying
up (like a room full of flaking paint).

Modified Paths:
--------------
    trunk/blender/source/blender/editors/space_view3d/view3d_select.c

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_select.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_select.c	2010-12-30 21:46:09 UTC (rev 33957)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_select.c	2010-12-31 03:35:34 UTC (rev 33958)
@@ -32,6 +32,7 @@
 #include <float.h>
 #include <assert.h>
 
+#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
 #include "DNA_curve_types.h"
 #include "DNA_meta_types.h"
@@ -1688,9 +1689,11 @@
 						bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY));
 						if(bone) {
 							if(select) {
-								bone->flag |= BONE_SELECTED;
-								bone_selected=1;
+								if ((bone->flag & BONE_UNSELECTABLE)==0) {
+									bone->flag |= BONE_SELECTED;
+									bone_selected=1;
 // XXX									select_actionchannel_by_name(base->object->action, bone->name, 1);
+								}
 							}
 							else {
 								bArmature *arm= base->object->data;
@@ -2053,6 +2056,67 @@
 }
 
 
+// NOTE: pose-bone case is copied from editbone case...
+static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y)
+{
+	struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData;
+	int mx = x - data->mval[0], my = y - data->mval[1];
+	float r = sqrt(mx*mx + my*my);
+	
+	if (r <= data->radius) {
+		if (data->select)
+			pchan->bone->flag |= BONE_SELECTED;
+		else
+			pchan->bone->flag &= ~BONE_SELECTED;
+		return 1;
+	}
+	return 0;
+}
+static void pose_circle_select(ViewContext *vc, int select, short *mval, float rad)
+{
+	struct {ViewContext *vc; short select, mval[2]; float radius; } data;
+	bPose *pose = vc->obact->pose;
+	bPoseChannel *pchan;
+	int change= FALSE;
+	
+	/* set vc->edit data */
+	data.select = select;
+	data.mval[0] = mval[0];
+	data.mval[1] = mval[1];
+	data.radius = rad;
+
+	ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
+	
+	/* check each PoseChannel... */
+	// TODO: could be optimised at some point
+	for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
+		short sco1[2], sco2[2], didpoint=0;
+		float vec[3];
+		
+		/* project head location to screenspace */
+		mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_head);
+		project_short(vc->ar, vec, sco1);
+		
+		/* project tail location to screenspace */
+		mul_v3_m4v3(vec, vc->obact->obmat, pchan->pose_tail);
+		project_short(vc->ar, vec, sco2);
+		
+		/* check if the head and/or tail is in the circle 
+		 *	- the call to check also does the selection already
+		 */
+		if (pchan_circle_doSelectJoint(&data, pchan, sco1[0], sco1[1]))
+			didpoint= 1;
+		if (pchan_circle_doSelectJoint(&data, pchan, sco2[0], sco2[1]))
+			didpoint= 1;
+		
+		change |= didpoint;
+	}
+
+	if (change) {
+		WM_main_add_notifier(NC_OBJECT|ND_BONE_SELECT, vc->obact);
+	}
+}
+
 static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head)
 {
 	struct {ViewContext *vc; short select, mval[2]; float radius; } *data = userData;
@@ -2172,8 +2236,9 @@
 	
 	select= (gesture_mode==GESTURE_MODAL_SELECT);
     
-	if(CTX_data_edit_object(C) || paint_facesel_test(obact) ||
-		(obact && obact->mode & OB_MODE_PARTICLE_EDIT)) {
+	if( CTX_data_edit_object(C) || paint_facesel_test(obact) ||
+		(obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) )
+	{
 		ViewContext vc;
 		short mval[2];
 		
@@ -2191,6 +2256,8 @@
 			paint_facesel_circle_select(&vc, select, mval, (float)radius);
 			WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
 		}
+		else if(obact->mode & OB_MODE_POSE)
+			pose_circle_select(&vc, select, mval, (float)radius);
 		else
 			return PE_circle_select(C, select, mval, (float)radius);
 	}





More information about the Bf-blender-cvs mailing list