[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44285] trunk/blender/source/blender/ editors/object/object_vgroup.c: Done BMESH_TODO in object/object_vgroup.c ( make getSurroundingVerts() use polys/loops instead of tessfaces).

Bastien Montagne montagne29 at wanadoo.fr
Mon Feb 20 23:16:28 CET 2012


Revision: 44285
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44285
Author:   mont29
Date:     2012-02-20 22:16:20 +0000 (Mon, 20 Feb 2012)
Log Message:
-----------
Done BMESH_TODO in object/object_vgroup.c (make getSurroundingVerts() use polys/loops instead of tessfaces).

Also done a few optimizations of related code (OBJECT_OT_vertex_group_fix operator).

Modified Paths:
--------------
    trunk/blender/source/blender/editors/object/object_vgroup.c

Modified: trunk/blender/source/blender/editors/object/object_vgroup.c
===================================================================
--- trunk/blender/source/blender/editors/object/object_vgroup.c	2012-02-20 22:04:29 UTC (rev 44284)
+++ trunk/blender/source/blender/editors/object/object_vgroup.c	2012-02-20 22:16:20 UTC (rev 44285)
@@ -48,6 +48,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_particle_types.h"
 
+#include "BLI_array.h"
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
@@ -748,100 +749,68 @@
 	}
 }
 
-/* This adds the indices of vertices to a list if they are not already present
-It returns the number that it added (0-2)
-It relies on verts having -1 for unassigned indices
-*/
-static int tryToAddVerts(int *verts, int length, int a, int b)
+/* This finds all of the vertices face-connected to vert by an edge and returns a
+ * MEM_allocated array of indices of size count.
+ * count is an int passed by reference so it can be assigned the value of the length here. */
+static int* getSurroundingVerts(Mesh *me, int vert, int *count)
 {
-	char containsA = FALSE;
-	char containsB = FALSE;
-	int added = 0;
-	int i;
-	for(i = 0; i < length && (!containsA || !containsB); i++) {
-		if(verts[i] == a) {
-			containsA = TRUE;
-		} else if(verts[i] == b) {
-			containsB = TRUE;
-		} else if(verts[i] == -1) {
-			if(!containsA) {
-				verts[i] = a;
-				containsA = TRUE;
-				added++;
-			} else if(!containsB){
-				verts[i] = b;
-				containsB = TRUE;
-				added++;
-			}
-		}
-	}
-	return added;
-}
+	MPoly *mp = me->mpoly;
+	int i = me->totpoly;
+	/* Instead of looping twice on all polys and loops, and use a temp array, let's rather
+	 * use a BLI_array, with a reasonable starting/reserved size (typically, there are not
+	 * many vertices face-linked to another one, even 8 might be too high...). */
+	int *verts = NULL;
+	BLI_array_declare(verts);
 
-/* BMESH_TODO - use MPoly's */
+	BLI_array_reserve(verts, 8);
+	while(i--) {
+		int j = mp->totloop;
+		int first_l = mp->totloop - 1;
+		MLoop *ml = &me->mloop[mp->loopstart];
+		while(j--) {
+			/* XXX This assume a vert can only be once in a poly, even though
+			 *     it seems logical to me, not totaly sure of that. */
+			if (ml->v == vert) {
+				int a, b, k;
+				if(j == first_l) {
+					/* We are on the first corner. */
+					a = ml[1].v;
+					b = ml[j].v;
+				}
+				else if(!j) {
+					/* We are on the last corner. */
+					a = (ml-1)->v;
+					b = me->mloop[mp->loopstart].v;
+				}
+				else {
+					a = (ml-1)->v;
+					b = (ml+1)->v;
+				}
 
-/* This finds all of the vertices connected to vert by an edge
-and returns an array of indices of size count
+				/* Append a and b verts to array, if not yet present. */
+				k = BLI_array_count(verts);
+				/* XXX Maybe a == b is enough? */
+				while(k-- && !(a == b && a == -1)) {
+					if(verts[k] == a)
+						a = -1;
+					else if(verts[k] == b)
+						b = -1;
+				}
+				if(a != -1)
+					BLI_array_append(verts, a);
+				if(b != -1)
+					BLI_array_append(verts, b);
 
-count is an int passed by reference so it can be assigned the value of the length here.
-*/
-static int* getSurroundingVerts(Mesh *me, int vert, int *count)
-{
-	int length = 0;
-	int *tverts;
-	int *verts = NULL;
-	MFace *mf = me->mface;
-	int totface = me->totface;
-	int found = 0;
-	int i;
-	for(i = 0; i < totface; i++, mf++) {
-		if(vert == mf->v1 || vert == mf->v2 || vert == mf->v3 || (mf->v4 &&vert == mf->v4)) {
-			length+=2;
-		}
-	}
-	if(!length) {
-		return NULL;
-	}
-	tverts = MEM_mallocN(sizeof(int)*length, "tempSurroundingVerts");
-	mf = me->mface;
-	for(i = 0; i < length; i++) {
-		tverts[i] = -1;
-	}
-	for(i = 0; i < totface; i++, mf++) {
-		int a=-1, b=-1;
-		if(mf->v1 == vert) {
-			a = mf->v2;
-			if(mf->v4) {
-				b = mf->v4;
-			} else {
-				b = mf->v3;
+				/* Vert found in this poly, we can go to next one! */
+				break;
 			}
-		} else if(mf->v2 == vert) {
-			a = mf->v1;
-			b = mf->v3;
-		} else if(mf->v3 == vert) {
-			a = mf->v2;
-			if(mf->v4) {
-				b = mf->v4;
-			} else {
-				b = mf->v1;
-			}
-		} else if (mf->v4 && mf->v4 == vert){
-			a = mf->v1;
-			b = mf->v3;
-		} else {
-			continue;
+			ml++;
 		}
-		found += tryToAddVerts(tverts, length, a, b);
+		mp++;
 	}
-	if(found) {
-		verts = MEM_mallocN(sizeof(int)* found, "surroundingVerts");
-		for(i = 0; i < found; i++) {
-			verts[i] = tverts[i];
-		}
-		*count = found;
-	}
-	MEM_freeN(tverts);
+
+	/* Do not free the array! */
+	*count = BLI_array_count(verts);
 	return verts;
 }
 
@@ -1087,12 +1056,11 @@
 
 	Mesh *me = ob->data;
 	MVert *mvert = me->mvert;
-	const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
 	int *verts = NULL;
+	if(!(me->editflag & ME_EDIT_VERT_SEL))
+		return;
 	for(i = 0; i < me->totvert && mvert; i++, mvert++) {
-		
-		if(use_vert_sel && (mvert->flag & SELECT)) {
-			
+		if(mvert->flag & SELECT) {
 			int count=0;
 			if((verts = getSurroundingVerts(me, i, &count))) {
 				MVert m;
@@ -1100,7 +1068,8 @@
 				int k;
 
 				DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
-				for(k = 0; k < count; k++) {
+				k = count;
+				while(k--) {
 					dm->getVert(dm, verts[k], &m);
 					p[k] = m;
 				}




More information about the Bf-blender-cvs mailing list