[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [45791] trunk/blender/source/blender: BMESH_TODO: randomize vertices working again.

Bastien Montagne montagne29 at wanadoo.fr
Thu Apr 19 20:53:33 CEST 2012


Revision: 45791
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=45791
Author:   mont29
Date:     2012-04-19 18:53:32 +0000 (Thu, 19 Apr 2012)
Log Message:
-----------
BMESH_TODO: randomize vertices working again.

That whole "element re-arrange" area could use some love, though (e.g. make a single vert operator with more options, as faces; and make faces work in edit mode, probably no more reasons to switch to object mode?). Post-release TODO, anyway.

Also spotted a glitch in BLI_rand code, imho, which makes first element of an array not guarantied to be shuffled by BLI_array_randomize()... No correction though, as this might/would affect other parts of the code!

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/intern/rand.c
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c

Modified: trunk/blender/source/blender/blenlib/intern/rand.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/rand.c	2012-04-19 17:26:22 UTC (rev 45790)
+++ trunk/blender/source/blender/blenlib/intern/rand.c	2012-04-19 18:53:32 UTC (rev 45791)
@@ -119,6 +119,8 @@
 
 	temp = malloc(elemSize);
 
+	/* XXX Shouldn’t it rather be "while (i--) {" ?
+	 *     Else we have no guaranty first (0) element has a chance to be shuffled... --mont29 */
 	while (--i) {
 		int j = rng_getInt(rng)%numElems;
 		if (i!=j) {

Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-04-19 17:26:22 UTC (rev 45790)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-04-19 18:53:32 UTC (rev 45791)
@@ -3604,6 +3604,10 @@
  * geometry anymore.  might need a sortof "swap"
  * function for bmesh elements. */
 
+/* TODO All this section could probably use a refresh...
+ *      face code works in object mode, does everything in one op, while vert uses several...
+ */
+
 typedef struct xvertsort {
 	int x; /* X screen-coordinate */
 	int org_idx; /* Original index of this vertex _in the mempool_ */
@@ -3908,75 +3912,66 @@
 	ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
 }
 
-#if 0
-/* called from buttons */
-static void hashvert_flag(EditMesh *em, int flag)
+/* ******************************* Randomize verts ************************* */
+static void hashvert_flag(BMEditMesh *em, int flag, unsigned int seed)
 {
-	/* switch vertex order using hash table */
-	EditVert *eve;
-	struct xvertsort *sortblock, *sb, onth, *newsort;
-	ListBase tbase;
-	int amount, a, b;
+	BMVert *ve;
+	BMIter iter;
+	char *block/* Just to mark protected vertices */, *t_blk;
+	int *randblock, *vmap, *t_idx, *r_idx;
+	int totvert, randomized = 0, /*protected = 0, */ i;
 
-	/* count */
-	eve = em->verts.first;
-	amount = 0;
-	while (eve) {
-		if (eve->f & flag) amount++;
-		eve = eve->next;
-	}
-	if (amount == 0) return;
+	totvert = em->bm->totvert;
 
-	/* allocate memory */
-	sb = sortblock = (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort) * amount, "sortremovedoub");
-	eve = em->verts.first;
-	while (eve) {
-		if (eve->f & flag) {
-			sb->v1 = eve;
-			sb++;
+	block = MEM_callocN(sizeof(char) * totvert, "randvert block");
+	randblock = MEM_callocN(sizeof(int) * totvert, "randvert randblock");
+	BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+		if (BM_elem_flag_test(ve, flag)) {
+			block[i] = FALSE;
+			randblock[randomized++] = i;
 		}
-		eve = eve->next;
-	}
-
-	BLI_srand(1);
-
-	sb = sortblock;
-	for (a = 0; a < amount; a++, sb++) {
-		b = (int)(amount * BLI_drand());
-		if (b >= 0 && b < amount) {
-			newsort = sortblock + b;
-			onth = *sb;
-			*sb = *newsort;
-			*newsort = onth;
+		else {
+			block[i] = TRUE;
 		}
 	}
+/*	protected = totvert - randomized;*/
+/*	printf("%d verts: %d to be randomized, %d protected…\n", totvert, randomized, protected);*/
+	if (randomized == 0)
+		return;
 
-	/* make temporal listbase */
-	tbase.first = tbase.last = 0;
-	sb = sortblock;
-	while (amount--) {
-		eve = sb->v1;
-		BLI_remlink(&em->verts, eve);
-		BLI_addtail(&tbase, eve);
-		sb++;
+	
+	/* Randomize non-protected vertices indices, and create an array mapping old idx to new
+	 *  from both blocks, keeping protected vertices at the same indices. */
+	vmap = randblock;
+	randblock = MEM_mallocN(sizeof(int) * randomized, "randvert randblock");
+	memcpy(randblock, vmap, randomized * sizeof(int));
+	BLI_array_randomize	((void*)randblock, sizeof(int), randomized, seed);
+	t_blk = block + totvert - 1;
+	t_idx = vmap + totvert - 1;
+	r_idx = randblock + randomized - 1;
+	for (i = totvert; i--; t_blk--, t_idx--) {
+		if (*t_blk) /* Protected! */
+			*t_idx = i;
+		else
+			*t_idx = *r_idx--;
 	}
 
-	BLI_movelisttolist(&em->verts, &tbase);
+	MEM_freeN(randblock);
+	MEM_freeN(block);
 
-	MEM_freeN(sortblock);
+	BM_mesh_remap(em->bm, vmap, NULL, NULL);
 
+	MEM_freeN(vmap);
 }
-#endif
 
-static int edbm_vertices_randomize_exec(bContext *C, wmOperator *UNUSED(op))
+static int edbm_vertices_randomize_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	BMEditMesh *em = BMEdit_FromObject(obedit);
-#if 1 /* BMESH TODO */
-	(void)em;
-#else
-	hashvert_flag(em, SELECT);
-#endif
+	unsigned int seed = RNA_int_get(op->ptr, "seed");
+
+	hashvert_flag(em, BM_ELEM_SELECT, seed);
+
 	return OPERATOR_FINISHED;
 }
 
@@ -3994,6 +3989,9 @@
 
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	/* Properties */
+	ot->prop = RNA_def_int(ot->srna, "seed", 0, 0, INT_MAX, "Seed", "Seed for the random generator", 0, 255);
 }
 
 /******end of qsort stuff ****/




More information about the Bf-blender-cvs mailing list