[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52908] trunk/blender/source/blender: use openmp to thread some common bmesh operations

Campbell Barton ideasman42 at gmail.com
Wed Dec 12 06:04:06 CET 2012


Revision: 52908
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52908
Author:   campbellbarton
Date:     2012-12-12 05:04:01 +0000 (Wed, 12 Dec 2012)
Log Message:
-----------
use openmp to thread some common bmesh operations
- BM_mesh_elem_toolflags_ensure / bmo_flag_layer_alloc / bmo_flag_layer_free / bmo_flag_layer_clear
- BM_mesh_select_flush
- EDBM_index_arrays_init

notes:
- mostly use openmp `sections` to split operations on vert/edge/face since this is a fairly minor change.
- split tool flag pool in 3, this means we can allocate exact sizes needed and iterate on them in threads without alloc'ing.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/bmesh_class.h
    trunk/blender/source/blender/bmesh/intern/bmesh_core.c
    trunk/blender/source/blender/bmesh/intern/bmesh_marking.c
    trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c
    trunk/blender/source/blender/bmesh/intern/bmesh_operators.c
    trunk/blender/source/blender/editors/mesh/editmesh_utils.c
    trunk/blender/source/blender/modifiers/intern/MOD_decimate.c

Modified: trunk/blender/source/blender/bmesh/bmesh_class.h
===================================================================
--- trunk/blender/source/blender/bmesh/bmesh_class.h	2012-12-12 04:50:53 UTC (rev 52907)
+++ trunk/blender/source/blender/bmesh/bmesh_class.h	2012-12-12 05:04:01 UTC (rev 52908)
@@ -187,8 +187,9 @@
 	/*element pools*/
 	struct BLI_mempool *vpool, *epool, *lpool, *fpool;
 
-	/*operator api stuff*/
-	struct BLI_mempool *toolflagpool;
+	/*operator api stuff (must be all NULL or all alloc'd)*/
+	struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
+
 	int stackdepth;
 	struct BMOperator *currentop;
 	

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_core.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_core.c	2012-12-12 04:50:53 UTC (rev 52907)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_core.c	2012-12-12 05:04:01 UTC (rev 52908)
@@ -79,8 +79,8 @@
 	}
 
 	/* allocate flags */
-	if (bm->toolflagpool) {
-		v->oflags = BLI_mempool_calloc(bm->toolflagpool);
+	if (bm->vtoolflagpool) {
+		v->oflags = BLI_mempool_calloc(bm->vtoolflagpool);
 	}
 
 	if (!(create_flag & BM_CREATE_SKIP_CD)) {
@@ -133,8 +133,8 @@
 	e->head.htype = BM_EDGE;
 	
 	/* allocate flags */
-	if (bm->toolflagpool) {
-		e->oflags = BLI_mempool_calloc(bm->toolflagpool);
+	if (bm->etoolflagpool) {
+		e->oflags = BLI_mempool_calloc(bm->etoolflagpool);
 	}
 
 	e->v1 = v1;
@@ -291,8 +291,8 @@
 	f->head.htype = BM_FACE;
 
 	/* allocate flags */
-	if (bm->toolflagpool) {
-		f->oflags = BLI_mempool_calloc(bm->toolflagpool);
+	if (bm->ftoolflagpool) {
+		f->oflags = BLI_mempool_calloc(bm->ftoolflagpool);
 	}
 
 	if (!(create_flag & BM_CREATE_SKIP_CD)) {
@@ -512,8 +512,8 @@
 	if (v->head.data)
 		CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
 
-	if (bm->toolflagpool) {
-		BLI_mempool_free(bm->toolflagpool, v->oflags);
+	if (bm->vtoolflagpool) {
+		BLI_mempool_free(bm->vtoolflagpool, v->oflags);
 	}
 	BLI_mempool_free(bm->vpool, v);
 }
@@ -532,8 +532,8 @@
 	if (e->head.data)
 		CustomData_bmesh_free_block(&bm->edata, &e->head.data);
 
-	if (bm->toolflagpool) {
-		BLI_mempool_free(bm->toolflagpool, e->oflags);
+	if (bm->etoolflagpool) {
+		BLI_mempool_free(bm->etoolflagpool, e->oflags);
 	}
 	BLI_mempool_free(bm->epool, e);
 }
@@ -555,8 +555,8 @@
 	if (f->head.data)
 		CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
 
-	if (bm->toolflagpool) {
-		BLI_mempool_free(bm->toolflagpool, f->oflags);
+	if (bm->ftoolflagpool) {
+		BLI_mempool_free(bm->ftoolflagpool, f->oflags);
 	}
 	BLI_mempool_free(bm->fpool, f);
 }
@@ -1785,8 +1785,8 @@
 	bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
 	
 	/* deallocate edge and its two loops as well as f2 */
-	if (bm->toolflagpool) {
-		BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
+	if (bm->etoolflagpool) {
+		BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags);
 	}
 	BLI_mempool_free(bm->epool, f1loop->e);
 	bm->totedge--;
@@ -1794,8 +1794,8 @@
 	bm->totloop--;
 	BLI_mempool_free(bm->lpool, f2loop);
 	bm->totloop--;
-	if (bm->toolflagpool) {
-		BLI_mempool_free(bm->toolflagpool, f2->oflags);
+	if (bm->ftoolflagpool) {
+		BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
 	}
 	BLI_mempool_free(bm->fpool, f2);
 	bm->totface--;

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_marking.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_marking.c	2012-12-12 04:50:53 UTC (rev 52907)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_marking.c	2012-12-12 05:04:01 UTC (rev 52908)
@@ -44,8 +44,6 @@
 
 static void recount_totsels(BMesh *bm)
 {
-	BMIter iter;
-	BMElem *ele;
 	const char iter_types[3] = {BM_VERTS_OF_MESH,
 	                            BM_EDGES_OF_MESH,
 	                            BM_FACES_OF_MESH};
@@ -58,11 +56,16 @@
 	tots[1] = &bm->totedgesel;
 	tots[2] = &bm->totfacesel;
 
+#pragma omp parallel for schedule(dynamic)
 	for (i = 0; i < 3; i++) {
-		ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
-		for ( ; ele; ele = BM_iter_step(&iter)) {
-			if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) *tots[i] += 1;
+		BMIter iter;
+		BMElem *ele;
+		int count = 0;
+
+		BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+			if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) count += 1;
 		}
+		*tots[i] = count;
 	}
 }
 
@@ -161,34 +164,45 @@
 
 	int ok;
 
-	BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
-		if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
-		      BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
-		      !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+	/* we can use 2 sections here because the second loop isnt checking edge selection */
+#pragma omp parallel sections
+	{
+#pragma omp section
 		{
-			BM_elem_flag_disable(e, BM_ELEM_SELECT);
+			BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+				if (!(BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+				      BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+				      !BM_elem_flag_test(e, BM_ELEM_HIDDEN)))
+				{
+					BM_elem_flag_disable(e, BM_ELEM_SELECT);
+				}
+			}
 		}
-	}
 
-	BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
-		ok = TRUE;
-		if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
-			l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-			do {
-				if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+#pragma omp section
+		{
+			BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+				ok = TRUE;
+				if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+					l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+					do {
+						if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+							ok = FALSE;
+							break;
+						}
+					} while ((l_iter = l_iter->next) != l_first);
+				}
+				else {
 					ok = FALSE;
-					break;
 				}
-			} while ((l_iter = l_iter->next) != l_first);
-		}
-		else {
-			ok = FALSE;
-		}
 
-		if (ok == FALSE) {
-			BM_elem_flag_disable(f, BM_ELEM_SELECT);
+				if (ok == FALSE) {
+					BM_elem_flag_disable(f, BM_ELEM_SELECT);
+				}
+			}
 		}
 	}
+	/* end sections */
 
 	/* Remove any deselected elements from the BMEditSelection */
 	BM_select_history_validate(bm);
@@ -212,32 +226,42 @@
 
 	int ok;
 
-	BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
-		if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
-		    BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
-		    !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+	/* we can use 2 sections here because the second loop isnt checking edge selection */
+#pragma omp parallel sections
+	{
+#pragma omp section
 		{
-			BM_elem_flag_enable(e, BM_ELEM_SELECT);
+			BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+				if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
+				    BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+				    !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
+				{
+					BM_elem_flag_enable(e, BM_ELEM_SELECT);
+				}
+			}
 		}
-	}
 
-	BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
-		ok = TRUE;
-		if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
-			l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-			do {
-				if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+#pragma omp section
+		{
+			BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+				ok = TRUE;
+				if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+					l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+					do {
+						if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+							ok = FALSE;
+							break;
+						}
+					} while ((l_iter = l_iter->next) != l_first);
+				}
+				else {
 					ok = FALSE;
-					break;
 				}
-			} while ((l_iter = l_iter->next) != l_first);
-		}
-		else {
-			ok = FALSE;
-		}
 
-		if (ok) {
-			BM_elem_flag_enable(f, BM_ELEM_SELECT);
+				if (ok) {
+					BM_elem_flag_enable(f, BM_ELEM_SELECT);
+				}
+			}
 		}
 	}
 
@@ -810,8 +834,6 @@
 
 	const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
 
-	BMIter iter;
-	BMElem *ele;
 	int i;
 
 	if (hflag & BM_ELEM_SELECT) {
@@ -825,16 +847,25 @@
 	{
 		/* fast path for deselect all, avoid topology loops
 		 * since we know all will be de-selected anyway. */
+
+#pragma omp parallel for schedule(dynamic)
 		for (i = 0; i < 3; i++) {
+			BMIter iter;
+			BMElem *ele;
+
 			ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
 			for ( ; ele; ele = BM_iter_step(&iter)) {
 				BM_elem_flag_disable(ele, BM_ELEM_SELECT);
 			}
 		}
+
 		bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
 	}
 	else {
 		for (i = 0; i < 3; i++) {
+			BMIter iter;
+			BMElem *ele;
+
 			if (htype & flag_types[i]) {
 				ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
 				for ( ; ele; ele = BM_iter_step(&iter)) {

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c	2012-12-12 04:50:53 UTC (rev 52907)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_mesh.c	2012-12-12 05:04:01 UTC (rev 52908)
@@ -63,41 +63,63 @@
 
 void BM_mesh_elem_toolflags_ensure(BMesh *bm)
 {
-	if (bm->toolflagpool == NULL) {
-		const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface);
-		BLI_mempool *toolflagpool;
+	if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) {
+		return;
+	}
 
-		BMIter iter;
-		BMElemF *ele;
-		const char iter_types[3] = {BM_VERTS_OF_MESH,
-		                            BM_EDGES_OF_MESH,
-		                            BM_FACES_OF_MESH};
+	bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totvert), 512, 0);
+	bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totedge), 512, 0);
+	bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), max_ii(512, bm->totface), 512, 0);
 
-		int i;
-
-		BLI_assert(bm->totflags == 0);
-
-		/* allocate one flag pool that we don't get rid of. */
-		toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0);
-
-
-		for (i = 0; i < 3; i++) {
-			BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+#pragma omp parallel sections
+	{
+#pragma omp section
+		{
+			BLI_mempool *toolflagpool = bm->vtoolflagpool;
+			BMIter iter;
+			BMElemF *ele;
+			BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
 				ele->oflags = BLI_mempool_calloc(toolflagpool);
 			}
 		}
+#pragma omp section
+		{
+			BLI_mempool *toolflagpool = bm->etoolflagpool;
+			BMIter iter;
+			BMElemF *ele;
+			BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+				ele->oflags = BLI_mempool_calloc(toolflagpool);
+			}
+		}
+#pragma omp section
+		{
+			BLI_mempool *toolflagpool = bm->ftoolflagpool;
+			BMIter iter;
+			BMElemF *ele;
+			BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list