[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22835] branches/bmesh/blender/source/ blender: Shift-G (select similar) is now bmeshafied for vert select mode.

Joseph Eagar joeedh at gmail.com
Fri Aug 28 12:59:18 CEST 2009


Revision: 22835
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22835
Author:   joeedh
Date:     2009-08-28 12:59:16 +0200 (Fri, 28 Aug 2009)

Log Message:
-----------
Shift-G (select similar) is now bmeshafied for vert select mode.
The patch was by Wael El Oraiby.

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h
    branches/bmesh/blender/source/blender/bmesh/operators/utils.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h	2009-08-28 10:17:31 UTC (rev 22834)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h	2009-08-28 10:59:16 UTC (rev 22835)
@@ -43,6 +43,13 @@
 	SIMEDGE_SHARP,
 };
 
+/* similar vertex selection slot values */
+enum {
+	SIMVERT_NORMAL = 0,
+	SIMVERT_FACE,
+	SIMVERT_VGROUP,
+};
+
 extern BMOpDefine *opdefines[];
 extern int bmesh_total_ops;
 

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2009-08-28 10:17:31 UTC (rev 22834)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2009-08-28 10:59:16 UTC (rev 22835)
@@ -645,6 +645,22 @@
 	0
 };
 
+/*
+  Similar vertices select
+
+  Select similar vertices (normal, face, vertex group,....).
+*/
+BMOpDefine def_similarverts = {
+	"similarverts",
+	{{BMOP_OPSLOT_ELEMENT_BUF, "verts"}, /* input vertices */
+	 {BMOP_OPSLOT_ELEMENT_BUF, "vertout"}, /* output vertices */
+	 {BMOP_OPSLOT_INT, "type"},			/* type of selection */
+	 {BMOP_OPSLOT_FLT, "thresh"},		/* threshold of selection */
+	 {0} /*null-terminating sentinel*/},
+	bmesh_similarverts_exec,
+	0
+};
+
 BMOpDefine *opdefines[] = {
 	&def_splitop,
 	&def_dupeop,
@@ -687,6 +703,7 @@
 	&def_collapse,
 	&def_similarfaces,
 	&def_similaredges,
+	&def_similarverts,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2009-08-28 10:17:31 UTC (rev 22834)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2009-08-28 10:59:16 UTC (rev 22835)
@@ -48,4 +48,5 @@
 void bmesh_collapse_exec(BMesh *bm, BMOperator *op);
 void bmesh_similarfaces_exec(BMesh *bm, BMOperator *op);
 void bmesh_similaredges_exec(BMesh *bm, BMOperator *op);
+void bmesh_similarverts_exec(BMesh *bm, BMOperator *op);
 #endif

Modified: branches/bmesh/blender/source/blender/bmesh/operators/utils.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/utils.c	2009-08-28 10:17:31 UTC (rev 22834)
+++ branches/bmesh/blender/source/blender/bmesh/operators/utils.c	2009-08-28 10:59:16 UTC (rev 22835)
@@ -839,3 +839,116 @@
 	BMO_Flag_To_Slot(bm, op, "edgeout", EDGE_MARK, BM_EDGE);
 }
 
+/******************************************************************************
+** Similar Vertices
+******************************************************************************/
+#define VERT_MARK	1
+
+typedef struct tmp_vert_ext {
+	BMVert *v;
+	union {
+		int num_faces; /* adjacent faces */
+		MDeformVert *dvert; /* deform vertex */
+	};
+} tmp_vert_ext;
+
+/*
+** select similar vertices: the choices are in the enum in source/blender/bmesh/bmesh_operators.h
+** choices are normal, face, vertex group...
+*/
+void bmesh_similarverts_exec(BMesh *bm, BMOperator *op)
+{
+	BMOIter vs_iter;	/* selected verts iterator */
+	BMIter v_iter;		/* mesh verts iterator */
+	BMVert *vs;		/* selected vertex */
+	BMVert *v;			/* mesh vertex */
+	tmp_vert_ext *v_ext = NULL;
+	int *indices = NULL;
+	int num_total = 0, num_sels = 0, i = 0, idx = 0;
+	int type = BMO_Get_Int(op, "type");
+	float thresh = BMO_Get_Float(op, "thresh");
+
+	num_total = BM_Count_Element(bm, BM_VERT);
+
+	/* iterate through all selected edges and mark them */
+	BMO_ITER(vs, &vs_iter, bm, op, "verts", BM_VERT) {
+		BMO_SetFlag(bm, vs, VERT_MARK);
+		num_sels++;
+	}
+
+	/* allocate memory for the selected vertices indices and for all temporary vertices */
+	indices	= (int*)MEM_mallocN(sizeof(int) * num_sels, "vertex indices");
+	v_ext = (tmp_vert_ext*)MEM_mallocN(sizeof(tmp_vert_ext) * num_total, "vertex extra");
+
+	/* loop through all the vertices and fill the vertices/indices structure */
+	BM_ITER(v, &v_iter, bm, BM_VERTS_OF_MESH, NULL) {
+		v_ext[i].v = v;
+		if (BMO_TestFlag(bm, v, VERT_MARK)) {
+			indices[idx] = i;
+			idx++;
+		}
+
+		switch( type ) {
+		case SIMVERT_FACE:
+			/* calling BM_Vert_FaceCount every time is time consumming, so call it only once per vertex */
+			v_ext[i].num_faces	= BM_Vert_FaceCount(v);
+			break;
+
+		case SIMVERT_VGROUP:
+			if( CustomData_has_layer(&(bm->vdata),CD_MDEFORMVERT) ) {
+				v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT);
+			} else v_ext[i].dvert = NULL;
+			break;
+		}
+
+		i++;
+	}
+
+	/* select the vertices if any */
+	for( i = 0; i < num_total; i++ ) {
+		v = v_ext[i].v;
+		if( !BMO_TestFlag(bm, v, VERT_MARK) && !BM_TestHFlag(v, BM_HIDDEN) ) {
+			int cont = 1;
+			for( idx = 0; idx < num_sels && cont == 1; idx++ ) {
+				vs = v_ext[indices[idx]].v;
+				switch( type ) {
+				case SIMVERT_NORMAL:
+					/* compare the angle between the normals */
+					if( VecAngle2(v->no, vs->no) / 180.0 <= thresh ) {
+						BMO_SetFlag(bm, v, VERT_MARK);
+						cont = 0;
+
+					}
+					break;
+				case SIMVERT_FACE:
+					/* number of adjacent faces */
+					if( v_ext[i].num_faces == v_ext[indices[idx]].num_faces ) {
+						BMO_SetFlag(bm, v, VERT_MARK);
+						cont = 0;
+					}
+					break;
+
+				case SIMVERT_VGROUP:
+					if( v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL ) {
+						int v1, v2;
+						for( v1 = 0; v1 < v_ext[i].dvert->totweight && cont == 1; v1++ ) {
+							for( v2 = 0; v2 < v_ext[indices[idx]].dvert->totweight; v2++ ) {
+								if( v_ext[i].dvert->dw[v1].def_nr == v_ext[indices[idx]].dvert->dw[v2].def_nr ) {
+									BMO_SetFlag(bm, v, VERT_MARK);
+									cont = 0;
+									break;
+								}
+							}
+						}
+					}
+					break;
+				}
+			}
+		}
+	}
+
+	MEM_freeN(indices);
+	MEM_freeN(v_ext);
+
+	BMO_Flag_To_Slot(bm, op, "vertout", VERT_MARK, BM_VERT);
+}

Modified: branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c
===================================================================
--- branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c	2009-08-28 10:17:31 UTC (rev 22834)
+++ branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c	2009-08-28 10:59:16 UTC (rev 22835)
@@ -975,13 +975,9 @@
  mode 3: same vertex groups
 */
 
-#define SIMVERT_NORMAL	0
-#define SIMVERT_FACE	1
-#define SIMVERT_VGROUP	2
-
 static EnumPropertyItem prop_simvertex_types[] = {
 	{SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
-	{SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""},
+	{SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""},
 	{SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
 	{0, NULL, 0, NULL, NULL}
 };
@@ -989,141 +985,38 @@
 
 static int similar_vert_select_exec(bContext *C, wmOperator *op)
 {
-#if 0
-	Scene *scene= CTX_data_scene(C);
-	Object *obedit= CTX_data_edit_object(C);
-	Mesh *me= obedit->data;
-	EditMesh *em= BKE_mesh_get_editmesh(me); 
-	EditVert *eve, *base_eve=NULL;
-	unsigned int selcount=0; /* count how many new edges we select*/
-	
-	/*count how many visible selected edges there are,
-	so we can return when there are none left */
-	unsigned int deselcount=0;
-	int mode= RNA_enum_get(op->ptr, "type");
-	
-	short ok=0;
-	float thresh= scene->toolsettings->select_thresh;
-	
-	for(eve= em->verts.first; eve; eve= eve->next) {
-		if (!eve->h) {
-			if (eve->f & SELECT) {
-				eve->f1=1;
-				ok=1;
-			} else {
-				eve->f1=0;
-				deselcount++;
-			}
-			/* set all eve->tmp.l to 0 we use them later.*/
-			eve->tmp.l=0;
-		}
-		
-	}
-	
-	if (!ok || !deselcount) { /* no data selected OR no more data to select*/
-		BKE_mesh_end_editmesh(me, em);
-		return 0;
-	}
-	
-	if(mode == SIMVERT_FACE) {
-		/* store face users */
-		EditFace *efa;
-		
-		/* count how many faces each edge uses use tmp->l */
-		for(efa= em->faces.first; efa; efa= efa->next) {
-			efa->v1->tmp.l++;
-			efa->v2->tmp.l++;
-			efa->v3->tmp.l++;
-			if (efa->v4) efa->v4->tmp.l++;
-		}
-	}
-	
-	
-	for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) {
-		if (base_eve->f1) {
-				
-			if(mode == SIMVERT_NORMAL) {
-				float angle;
-				for(eve= em->verts.first; eve; eve= eve->next) {
-					if (!(eve->f & SELECT) && !eve->h) {
-						angle= VecAngle2(base_eve->no, eve->no);
-						if (angle/180.0<=thresh) {
-							eve->f |= SELECT;
-							selcount++;
-							deselcount--;
-							if (!deselcount) {/*have we selected all posible faces?, if so return*/
-								BKE_mesh_end_editmesh(me, em);
-								return selcount;
-							}
-						}
-					}
-				}
-			}
-			else if(mode == SIMVERT_FACE) {
-				for(eve= em->verts.first; eve; eve= eve->next) {
-					if (
-						!(eve->f & SELECT) &&
-						!eve->h &&
-						base_eve->tmp.l==eve->tmp.l
-					) {
-						eve->f |= SELECT;
-						selcount++;
-						deselcount--;
-						if (!deselcount) {/*have we selected all posible faces?, if so return*/
-							BKE_mesh_end_editmesh(me, em);
-							return selcount;
-						}
-					}
-				}
-			} 
-			else if(mode == SIMVERT_VGROUP) {
-				MDeformVert *dvert, *base_dvert;
-				short i, j; /* weight index */
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = CTX_data_edit_object(C);
+	BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
+	BMOperator bmop;
+	/* get the type from RNA */
+	int type = RNA_enum_get(op->ptr, "type");
+	float thresh = scene->toolsettings->select_thresh;
 
-				base_dvert= CustomData_em_get(&em->vdata, base_eve->data,
-					CD_MDEFORMVERT);
+	/* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */
+	EDBM_InitOpf(em, &bmop, op, "similarverts verts=%hv type=%d thresh=%f", BM_SELECT, type, thresh);
 
-				if (!base_dvert || base_dvert->totweight == 0) {
-					BKE_mesh_end_editmesh(me, em);
-					return selcount;
-				}
-				
-				for(eve= em->verts.first; eve; eve= eve->next) {
-					dvert= CustomData_em_get(&em->vdata, eve->data,
-						CD_MDEFORMVERT);
+	/* execute the operator */
+	BMO_Exec_Op(em->bm, &bmop);
 
-					if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) {
-						/* do the extra check for selection in the following if, so were not
-						checking verts that may be alredy selected */
-						for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) { 
-							for (j=0; dvert->totweight >j; j++) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list