[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [57062] trunk/blender/source/blender: optimize mirror merging, remove array reallocation, replace with fixed size arrays.

Campbell Barton ideasman42 at gmail.com
Mon May 27 22:11:12 CEST 2013


Revision: 57062
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=57062
Author:   campbellbarton
Date:     2013-05-27 20:11:12 +0000 (Mon, 27 May 2013)
Log Message:
-----------
optimize mirror merging, remove array reallocation, replace with fixed size arrays.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h
    trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
    trunk/blender/source/blender/blenlib/BLI_utildefines.h
    trunk/blender/source/blender/modifiers/intern/MOD_mirror.c

Modified: trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h	2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/blenkernel/BKE_cdderivedmesh.h	2013-05-27 20:11:12 UTC (rev 57062)
@@ -61,7 +61,7 @@
 DerivedMesh *CDDM_from_editbmesh(struct BMEditMesh *em, int use_mdisps, int use_tessface);
 
 /* merge verts  */
-DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap);
+DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int tot_vtargetmap);
 
 /* creates a CDDerivedMesh from the given curve object */
 struct DerivedMesh *CDDM_from_curve(struct Object *ob);

Modified: trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/blenkernel/intern/cdderivedmesh.c	2013-05-27 20:11:12 UTC (rev 57062)
@@ -2308,15 +2308,19 @@
 }
 
 #if 1
-/* merge verts
+
+/**
+ * Merge Verts
  *
- * vtargetmap is a table that maps vertices to target vertices.  a value of -1
+ * \param vtargetmap  The table that maps vertices to target vertices.  a value of -1
  * indicates a vertex is a target, and is to be kept.
+ * This array is aligned with 'dm->numVertData'
  *
+ * \param tot_vtargetmap  The number of non '-1' values in vtargetmap.
+ * (not the size )
+ *
  * this frees dm, and returns a new one.
  *
- * this is a really horribly written function.  ger. - joeedh
- *
  * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
  *
  * Note: This function is currently only used by the Mirror modifier, so it
@@ -2324,49 +2328,66 @@
  *       of faces sharing the same set of vertices). If used elsewhere, it may
  *       be necessary to make this functionality optional.
  */
-DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
+DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int tot_vtargetmap)
 {
 // #define USE_LOOPS
 	CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
 	CDDerivedMesh *cddm2 = NULL;
-	MVert *mv, *mvert = NULL;
-	BLI_array_declare(mvert);
-	MEdge *med, *medge = NULL;
-	BLI_array_declare(medge);
-	MPoly *mp, *mpoly = NULL;
-	BLI_array_declare(mpoly);
-	MLoop *ml, *mloop = NULL;
-	BLI_array_declare(mloop);
-	EdgeHash *ehash = BLI_edgehash_new();
-	int *newv = NULL, *newe = NULL;
+
+	const int totvert = dm->numVertData;
+	const int totedge = dm->numEdgeData;
+	const int totloop = dm->numLoopData;
+	const int totpoly = dm->numPolyData;
+
+	const int totvert_final = totvert - tot_vtargetmap;
+
+	MVert *mv, *mvert = MEM_mallocN(sizeof(*mvert) * totvert_final, __func__);
+	int *oldv         = MEM_mallocN(sizeof(*oldv)  * totvert_final, __func__);
+	int *newv         = MEM_mallocN(sizeof(*newv)  * totvert, __func__);
+	STACK_DECLARE(mvert);
+	STACK_DECLARE(oldv);
+
+	MEdge *med, *medge = MEM_mallocN(sizeof(*medge) * totedge, __func__);
+	int *olde          = MEM_mallocN(sizeof(*olde)  * totedge, __func__);
+	int *newe          = MEM_mallocN(sizeof(*newe)  * totedge, __func__);
+	STACK_DECLARE(medge);
+	STACK_DECLARE(olde);
+
+	MLoop *ml, *mloop = MEM_mallocN(sizeof(*mloop) * totloop, __func__);
+	int *oldl         = MEM_mallocN(sizeof(*oldl)  * totloop, __func__);
 #ifdef USE_LOOPS
-	int *newl = NULL;
+	int newl          = MEM_mallocN(sizeof(*newl)  * totloop, __func__);
 #endif
-	int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
-	BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
-	int i, j, c, totpoly;
-#ifdef USE_LOOPS
-	int totloop;
-#endif
+	STACK_DECLARE(mloop);
+	STACK_DECLARE(oldl);
 
-#ifdef USE_LOOPS
-	totloop = dm->numLoopData;
-#endif
-	totpoly = dm->numPolyData;
+	MPoly *mp, *mpoly = MEM_mallocN(sizeof(*medge) * totpoly, __func__);
+	int *oldp         = MEM_mallocN(sizeof(*oldp)  * totpoly, __func__);
+	STACK_DECLARE(mpoly);
+	STACK_DECLARE(oldp);
+
+	EdgeHash *ehash = BLI_edgehash_new();
+
+	int i, j, c;
 	
-	newv = MEM_mallocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
-	newe = MEM_mallocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
-#ifdef USE_LOOPS
-	newl = MEM_mallocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
-#endif
+	STACK_INIT(oldv);
+	STACK_INIT(olde);
+	STACK_INIT(oldl);
+	STACK_INIT(oldp);
+
+	STACK_INIT(mvert);
+	STACK_INIT(medge);
+	STACK_INIT(mloop);
+	STACK_INIT(mpoly);
+
 	/* fill newl with destination vertex indices */
 	mv = cddm->mvert;
 	c = 0;
-	for (i = 0; i < dm->numVertData; i++, mv++) {
+	for (i = 0; i < totvert; i++, mv++) {
 		if (vtargetmap[i] == -1) {
-			BLI_array_append(oldv, i);
+			STACK_PUSH(oldv, i);
+			STACK_PUSH(mvert, *mv);
 			newv[i] = c++;
-			BLI_array_append(mvert, *mv);
 		}
 		else {
 			/* dummy value */
@@ -2375,7 +2396,7 @@
 	}
 	
 	/* now link target vertices to destination indices */
-	for (i = 0; i < dm->numVertData; i++) {
+	for (i = 0; i < totvert; i++) {
 		if (vtargetmap[i] != -1) {
 			newv[i] = newv[vtargetmap[i]];
 		}
@@ -2389,7 +2410,7 @@
 	/* now go through and fix edges and faces */
 	med = cddm->medge;
 	c = 0;
-	for (i = 0; i < dm->numEdgeData; i++, med++) {
+	for (i = 0; i < totedge; i++, med++) {
 		
 		if (LIKELY(med->v1 != med->v2)) {
 			const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
@@ -2400,9 +2421,9 @@
 				newe[i] = GET_INT_FROM_POINTER(*eh_p);
 			}
 			else {
-				BLI_array_append(olde, i);
+				STACK_PUSH(olde, i);
+				STACK_PUSH(medge, *med);
 				newe[i] = c;
-				BLI_array_append(medge, *med);
 				BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
 				c++;
 			}
@@ -2414,7 +2435,7 @@
 	
 	mp = cddm->mpoly;
 	for (i = 0; i < totpoly; i++, mp++) {
-		MPoly *mp2;
+		MPoly *mp_new;
 		
 		ml = cddm->mloop + mp->loopstart;
 
@@ -2441,10 +2462,10 @@
 			med = cddm->medge + ml->e;
 			if (LIKELY(med->v1 != med->v2)) {
 #ifdef USE_LOOPS
-				newl[j + mp->loopstart] = BLI_array_count(mloop);
+				newl[j + mp->loopstart] = STACK_SIZE(mloop);
 #endif
-				BLI_array_append(oldl, j + mp->loopstart);
-				BLI_array_append(mloop, *ml);
+				STACK_PUSH(oldl, j + mp->loopstart);
+				STACK_PUSH(mloop, *ml);
 				c++;
 			}
 		}
@@ -2452,16 +2473,17 @@
 		if (UNLIKELY(c == 0)) {
 			continue;
 		}
+
+		mp_new = STACK_PUSH_RET_PTR(mpoly);
+		*mp_new = *mp;
+		mp_new->totloop = c;
+		mp_new->loopstart = STACK_SIZE(mloop) - c;
 		
-		mp2 = BLI_array_append_r(mpoly, *mp);
-		mp2->totloop = c;
-		mp2->loopstart = BLI_array_count(mloop) - c;
-		
-		BLI_array_append(oldp, i);
+		STACK_PUSH(oldp, i);
 	}
 	
 	/*create new cddm*/
-	cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
+	cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
 	
 	/*update edge indices and copy customdata*/
 	med = medge;
@@ -2498,31 +2520,39 @@
 	}
 	
 	/*copy over data.  CustomData_add_layer can do this, need to look it up.*/
-	memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
-	memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
-	memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
-	memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
-	BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
-	
-	if (newv) 
-		MEM_freeN(newv); 
-	if (newe)
-		MEM_freeN(newe); 
+	memcpy(cddm2->mvert, mvert, sizeof(MVert) * STACK_SIZE(mvert));
+	memcpy(cddm2->medge, medge, sizeof(MEdge) * STACK_SIZE(medge));
+	memcpy(cddm2->mloop, mloop, sizeof(MLoop) * STACK_SIZE(mloop));
+	memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
+
+	MEM_freeN(mvert);
+	MEM_freeN(medge);
+	MEM_freeN(mloop);
+	MEM_freeN(mpoly);
+
+	MEM_freeN(newv);
+	MEM_freeN(newe);
 #ifdef USE_LOOPS
-	if (newl)
-		MEM_freeN(newl);
+	MEM_freeN(newl);
 #endif
-	if (oldv) 
-		MEM_freeN(oldv); 
-	if (olde) 
-		MEM_freeN(olde); 
-	if (oldl) 
-		MEM_freeN(oldl); 
-	if (oldp) 
-		MEM_freeN(oldp);
-	if (ehash)
-		BLI_edgehash_free(ehash, NULL);
 
+	MEM_freeN(oldv);
+	MEM_freeN(olde);
+	MEM_freeN(oldl);
+	MEM_freeN(oldp);
+
+	STACK_FREE(oldv);
+	STACK_FREE(olde);
+	STACK_FREE(oldl);
+	STACK_FREE(oldp);
+
+	STACK_FREE(mvert);
+	STACK_FREE(medge);
+	STACK_FREE(mloop);
+	STACK_FREE(mpoly);
+
+	BLI_edgehash_free(ehash, NULL);
+
 	/*free old derivedmesh*/
 	dm->needsFree = 1;
 	dm->release(dm);

Modified: trunk/blender/source/blender/blenlib/BLI_utildefines.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_utildefines.h	2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/blenlib/BLI_utildefines.h	2013-05-27 20:11:12 UTC (rev 57062)
@@ -296,6 +296,7 @@
 #define STACK_SIZE(stack)      ((void)stack, (_##stack##_index))
 #define STACK_PUSH(stack, val)  (void)((stack)[(_##stack##_index)++] = val)
 #define STACK_PUSH_RET(stack)  ((void)stack, ((stack)[(_##stack##_index)++]))
+#define STACK_PUSH_RET_PTR(stack)  ((void)stack, &((stack)[(_##stack##_index)++]))
 #define STACK_POP(stack)       ((_##stack##_index) ? ((stack)[--(_##stack##_index)]) : NULL)
 #define STACK_FREE(stack)      ((void)stack)
 

Modified: trunk/blender/source/blender/modifiers/intern/MOD_mirror.c
===================================================================
--- trunk/blender/source/blender/modifiers/intern/MOD_mirror.c	2013-05-27 18:51:31 UTC (rev 57061)
+++ trunk/blender/source/blender/modifiers/intern/MOD_mirror.c	2013-05-27 20:11:12 UTC (rev 57062)
@@ -99,7 +99,7 @@
 {
 	const float tolerance_sq = mmd->tolerance * mmd->tolerance;
 	const int do_vtargetmap = !(mmd->flag & MOD_MIR_NO_MERGE);
-	int is_vtargetmap = FALSE; /* true when it should be used */
+	int tot_vtargetmap = 0;  /* total merge vertices */
 
 	DerivedMesh *result;
 	const int maxVerts = dm->getNumVerts(dm);
@@ -187,7 +187,7 @@
 			 * should be mapped for merging */
 			if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) {
 				*vtmap_a = maxVerts + i;
-				is_vtargetmap = TRUE;
+				tot_vtargetmap++;
 			}
 			else {
 				*vtmap_a = -1;
@@ -288,8 +288,8 @@
 	if (do_vtargetmap) {

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list